Skip to content

Commit

Permalink
tempname(cleanup=true|false): add cleanup keyword to tempname
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed Aug 27, 2019
1 parent 788acce commit 625fab3
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ New library functions

* The `splitpath` function now accepts any `AbstractString` whereas previously it only accepted paths of type `String` ([#33012]).
* The `tempname` function now takes an optional `parent::AbstractString` argument to give it a directory in which to attempt to produce a temporary path name ([#33090]).
* The `tempname` function now takes a `cleanup::Bool` keyword argument defaulting to `false`; when set to `true` the process will try to ensure that any file or directory at the path returned by `tempname` is deleted upon process exit ([#33090]).


Standard library changes
Expand Down
17 changes: 13 additions & 4 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ function mktemp(parent::AbstractString=tempdir(); cleanup::Bool=true)
return (filename, Base.open(filename, "r+"))
end

function tempname(parent::AbstractString=tempdir())
function tempname(parent::AbstractString=tempdir(); cleanup::Bool=false)
isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory"))
seed::UInt32 = rand(UInt32)
while true
Expand All @@ -509,6 +509,7 @@ function tempname(parent::AbstractString=tempdir())
end
filename = _win_tempname(parent, seed)
if !ispath(filename)
cleanup && temp_cleanup_later(filename)
return filename
end
seed += 1
Expand All @@ -518,12 +519,13 @@ end
else # !windows

# Obtain a temporary filename.
function tempname(parent::AbstractString=tempdir())
function tempname(parent::AbstractString=tempdir(); cleanup::Bool=false)
isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory"))
p = ccall(:tempnam, Cstring, (Cstring, Cstring), parent, temp_prefix)
systemerror(:tempnam, p == C_NULL)
s = unsafe_string(p)
Libc.free(p)
cleanup && temp_cleanup_later(s)
return s
end

Expand All @@ -541,7 +543,7 @@ end # os-test


"""
tempname(parent=tempdir()) -> String
tempname(parent=tempdir(); cleanup=false) -> String
Generate a temporary file path. This function only returns a path; no file is
created. The path is likely to be unique, but this cannot be guaranteed due to
Expand All @@ -554,8 +556,15 @@ temporary name in the system temporary directory as given by `tempdir()`. If a
`parent` directory argument is given, the temporary path will be in that
directory instead.
The `cleanup` option controls whether the process attempts to delete the
returned path automatically when the process exits. Note that the `tempname`
function does not create any file or directory at the returned location, so
there is nothing to cleanup unless you create a file or directory there. If
you do and `clean` is `true` it will be deleted upon process termination.
!!! compat "Julia 1.4"
The `parent` argument was added in 1.4.
The `parent` and `cleanup` arguments were added in 1.4. Prior to Julia 1.4
the path `tempname` would never be cleaned up at process termination.
!!! warning
Expand Down
8 changes: 8 additions & 0 deletions test/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ child_eval(code::String) = eval(Meta.parse(readchomp(`$(Base.julia_cmd()) -E $co
# mktempdir with cleanup
t = child_eval("t = mktempdir(); touch(joinpath(t, \"file.txt\")); t")
@test !ispath(t)
# tempname without cleanup
t = child_eval("t = tempname(); touch(t); t")
@test isfile(t)
rm(t, force=true)
@test !ispath(t)
# tempname with cleanup
t = child_eval("t = tempname(cleanup=true); touch(t); t")
@test !ispath(t)
end

import Base.Filesystem: TEMP_CLEANUP_MIN, TEMP_CLEANUP_MAX, TEMP_CLEANUP
Expand Down

0 comments on commit 625fab3

Please sign in to comment.