Skip to content

Commit 50d8320

Browse files
committed
make tempname on windows match unix behavior. fixes #9053
also deprecate `tempname(::UInt32)` and add a warning to the docs.
1 parent 1c68f8a commit 50d8320

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

NEWS.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@ This section lists changes that do not have deprecation warnings.
385385
to get the old behavior (only "space" characters are considered as
386386
word separators), use the keyword `wordsep=isspace`.
387387

388+
* The `tempname` function used to create a file on Windows but not on other
389+
platforms. It now never creates a file ([#9053]).
390+
388391
Library improvements
389392
--------------------
390393

@@ -1191,4 +1194,4 @@ Command-line option changes
11911194
[#25231]: https://github.com/JuliaLang/julia/issues/25231
11921195
[#25365]: https://github.com/JuliaLang/julia/issues/25365
11931196
[#25424]: https://github.com/JuliaLang/julia/issues/25424
1194-
[#25532]: https://github.com/JuliaLang/julia/issues/25532
1197+
[#25532]: https://github.com/JuliaLang/julia/issues/25532

base/deprecated.jl

+7
Original file line numberDiff line numberDiff line change
@@ -2782,6 +2782,13 @@ end
27822782
@deprecate findn(x::AbstractMatrix) (I = find(!iszero, x); (getindex.(I, 1), getindex.(I, 2)))
27832783
@deprecate findn(a::AbstractArray{T, N}) where {T, N} (I = find(!iszero, x); ntuple(i -> getindex.(I, i), N))
27842784

2785+
# issue #9053
2786+
if Sys.iswindows()
2787+
function Filesystem.tempname(uunique::UInt32)
2788+
error("`tempname(::UInt32)` is discontinued.")
2789+
end
2790+
end
2791+
27852792
# END 0.7 deprecations
27862793

27872794
# BEGIN 1.0 deprecations

base/file.jl

+27-5
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ function tempdir()
265265
resize!(temppath,lentemppath)
266266
return transcode(String, temppath)
267267
end
268-
tempname(uunique::UInt32=UInt32(0)) = tempname(tempdir(), uunique)
268+
269269
const temp_prefix = cwstring("jl_")
270-
function tempname(temppath::AbstractString,uunique::UInt32)
270+
function _win_tempname(temppath::AbstractString, uunique::UInt32)
271271
tempp = cwstring(temppath)
272272
tname = Vector{UInt16}(uninitialized, 32767)
273273
uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname)
@@ -280,7 +280,7 @@ function tempname(temppath::AbstractString,uunique::UInt32)
280280
end
281281

282282
function mktemp(parent=tempdir())
283-
filename = tempname(parent, UInt32(0))
283+
filename = _win_tempname(parent, UInt32(0))
284284
return (filename, Base.open(filename, "r+"))
285285
end
286286

@@ -290,7 +290,7 @@ function mktempdir(parent=tempdir())
290290
if (seed & typemax(UInt16)) == 0
291291
seed += 1
292292
end
293-
filename = tempname(parent, seed)
293+
filename = _win_tempname(parent, seed)
294294
ret = ccall(:_wmkdir, Int32, (Ptr{UInt16},), cwstring(filename))
295295
if ret == 0
296296
return filename
@@ -300,6 +300,21 @@ function mktempdir(parent=tempdir())
300300
end
301301
end
302302

303+
function tempname()
304+
parent = tempdir()
305+
seed::UInt32 = rand(UInt32)
306+
while true
307+
if (seed & typemax(UInt16)) == 0
308+
seed += 1
309+
end
310+
filename = _win_tempname(parent, seed)
311+
if !ispath(filename)
312+
return filename
313+
end
314+
seed += 1
315+
end
316+
end
317+
303318
else # !windows
304319
# Obtain a temporary filename.
305320
function tempname()
@@ -343,7 +358,14 @@ tempdir()
343358
"""
344359
tempname()
345360
346-
Generate a unique temporary file path.
361+
Generate a temporary file path. This function only returns a path; no file is
362+
created. The path is likely to be unique, but this cannot be guaranteed.
363+
364+
!!! warning
365+
366+
This can lead to race conditions if another process obtains the same
367+
file name and creates the file before you are able to.
368+
Using [`mktemp()`](@ref) is recommended instead.
347369
"""
348370
tempname()
349371

base/pkg/entry.jl

+5-11
Original file line numberDiff line numberDiff line change
@@ -633,19 +633,13 @@ function build!(pkgs::Vector, seen::Set, errfile::AbstractString)
633633
end
634634

635635
function build!(pkgs::Vector, errs::Dict, seen::Set=Set())
636-
errfile = tempname()
637-
touch(errfile) # create empty file
638-
try
636+
mktemp() do errfile, f
639637
build!(pkgs, seen, errfile)
640-
open(errfile, "r") do f
641-
while !eof(f)
642-
pkg = deserialize(f)
643-
err = deserialize(f)
644-
errs[pkg] = err
645-
end
638+
while !eof(f)
639+
pkg = deserialize(f)
640+
err = deserialize(f)
641+
errs[pkg] = err
646642
end
647-
finally
648-
isfile(errfile) && Base.rm(errfile)
649643
end
650644
end
651645

test/file.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,10 @@ close(s)
218218
my_tempdir = tempdir()
219219
@test isdir(my_tempdir) == true
220220

221-
path = tempname()
222-
# Issue #9053.
223-
@test ispath(path) == Sys.iswindows()
224-
ispath(path) && rm(path)
221+
let path = tempname()
222+
# issue #9053
223+
@test !ispath(path)
224+
end
225225

226226
(p, f) = mktemp()
227227
print(f, "Here is some text")

0 commit comments

Comments
 (0)