Skip to content

Commit 788acce

Browse files
tempname(parent): add optional parent argument to tempname
1 parent b5c4e63 commit 788acce

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ New library functions
2121
---------------------
2222

2323
* The `splitpath` function now accepts any `AbstractString` whereas previously it only accepted paths of type `String` ([#33012]).
24+
* 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]).
2425

2526

2627
Standard library changes

base/file.jl

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,8 @@ function mktemp(parent::AbstractString=tempdir(); cleanup::Bool=true)
500500
return (filename, Base.open(filename, "r+"))
501501
end
502502

503-
function tempname()
504-
parent = tempdir()
503+
function tempname(parent::AbstractString=tempdir())
504+
isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory"))
505505
seed::UInt32 = rand(UInt32)
506506
while true
507507
if (seed & typemax(UInt16)) == 0
@@ -516,10 +516,11 @@ function tempname()
516516
end
517517

518518
else # !windows
519+
519520
# Obtain a temporary filename.
520-
function tempname()
521-
d = tempdir() # tempnam ignores TMPDIR on darwin
522-
p = ccall(:tempnam, Cstring, (Cstring, Cstring), d, temp_prefix)
521+
function tempname(parent::AbstractString=tempdir())
522+
isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory"))
523+
p = ccall(:tempnam, Cstring, (Cstring, Cstring), parent, temp_prefix)
523524
systemerror(:tempnam, p == C_NULL)
524525
s = unsafe_string(p)
525526
Libc.free(p)
@@ -540,16 +541,28 @@ end # os-test
540541

541542

542543
"""
543-
tempname()
544+
tempname(parent=tempdir()) -> String
544545
545546
Generate a temporary file path. This function only returns a path; no file is
546-
created. The path is likely to be unique, but this cannot be guaranteed.
547+
created. The path is likely to be unique, but this cannot be guaranteed due to
548+
the very remote posibility of two simultaneous calls to `tempname` generating
549+
the same file name. The name is guaranteed to differ from all files already
550+
existing at the time of the call to `tempname`.
551+
552+
When called with no arguments, the temporary name will be an absolute path to a
553+
temporary name in the system temporary directory as given by `tempdir()`. If a
554+
`parent` directory argument is given, the temporary path will be in that
555+
directory instead.
556+
557+
!!! compat "Julia 1.4"
558+
The `parent` argument was added in 1.4.
547559
548560
!!! warning
549561
550562
This can lead to security holes if another process obtains the same
551563
file name and creates the file before you are able to. Open the file with
552-
`JL_O_EXCL` if this is a concern. Using [`mktemp()`](@ref) is also recommended instead.
564+
`JL_O_EXCL` if this is a concern. Using [`mktemp()`](@ref) is also
565+
recommended instead.
553566
"""
554567
tempname()
555568

test/file.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ if !Sys.iswindows()
4848
cd(pwd_)
4949
end
5050

51+
using Random
52+
53+
@testset "tempname with parent" begin
54+
t = tempname()
55+
@test dirname(t) == tempdir()
56+
mktempdir() do d
57+
t = tempname(d)
58+
@test dirname(t) == d
59+
end
60+
@test_throws ArgumentError tempname(randstring())
61+
end
62+
5163
child_eval(code::String) = eval(Meta.parse(readchomp(`$(Base.julia_cmd()) -E $code`)))
5264

5365
@testset "mktemp/dir basic cleanup" begin

0 commit comments

Comments
 (0)