@@ -458,6 +458,32 @@ function tempdir()
458458 end
459459end
460460
461+ """
462+ prepare_for_deletion(path::AbstractString)
463+
464+ Prepares the given `path` for deletion by ensuring that all directories within that
465+ `path` have write permissions, so that files can be removed from them. This is
466+ automatically invoked by methods such as `mktempdir()` to ensure that no matter what
467+ weird permissions a user may have created directories with within the temporary prefix,
468+ it will always be deleted.
469+ """
470+ function prepare_for_deletion (path:: AbstractString )
471+ # Nothing to do for non-directories
472+ if ! isdir (path)
473+ return
474+ end
475+
476+ try chmod (path, filemode (path) | 0o333 )
477+ catch ; end
478+ for (root, dirs, files) in walkdir (path)
479+ for dir in dirs
480+ dpath = joinpath (root, dir)
481+ try chmod (dpath, filemode (dpath) | 0o333 )
482+ catch ; end
483+ end
484+ end
485+ end
486+
461487const TEMP_CLEANUP_MIN = Ref (1024 )
462488const TEMP_CLEANUP_MAX = Ref (1024 )
463489const TEMP_CLEANUP = Dict {String,Bool} ()
@@ -484,6 +510,7 @@ function temp_cleanup_purge(all::Bool=true)
484510 if (all || asap) && ispath (path)
485511 need_gc && GC. gc (true )
486512 need_gc = false
513+ prepare_for_deletion (path)
487514 rm (path, recursive= true , force= true )
488515 end
489516 ! ispath (path) && delete! (TEMP_CLEANUP, path)
@@ -682,7 +709,10 @@ function mktempdir(fn::Function, parent::AbstractString=tempdir();
682709 fn (tmpdir)
683710 finally
684711 try
685- ispath (tmpdir) && rm (tmpdir, recursive= true )
712+ if ispath (tmpdir)
713+ prepare_for_deletion (tmpdir)
714+ rm (tmpdir, recursive= true )
715+ end
686716 catch ex
687717 @error " mktempdir cleanup" _group= :file exception= (ex, catch_backtrace ())
688718 # might be possible to remove later
0 commit comments