Skip to content

Commit 5e2ff12

Browse files
authored
make tempname on windows match unix behavior. fixes #9053 (#25530)
also deprecate `tempname(::UInt32)` and add a warning to the docs.
1 parent e88cbd9 commit 5e2ff12

File tree

6 files changed

+48
-21
lines changed

6 files changed

+48
-21
lines changed

NEWS.md

Lines changed: 4 additions & 1 deletion
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

@@ -1194,4 +1197,4 @@ Command-line option changes
11941197
[#25231]: https://github.com/JuliaLang/julia/issues/25231
11951198
[#25365]: https://github.com/JuliaLang/julia/issues/25365
11961199
[#25424]: https://github.com/JuliaLang/julia/issues/25424
1197-
[#25532]: https://github.com/JuliaLang/julia/issues/25532
1200+
[#25532]: https://github.com/JuliaLang/julia/issues/25532

base/deprecated.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,13 @@ end
27892789
@deprecate findn(x::AbstractMatrix) (I = find(!iszero, x); (getindex.(I, 1), getindex.(I, 2)))
27902790
@deprecate findn(a::AbstractArray{T, N}) where {T, N} (I = find(!iszero, x); ntuple(i -> getindex.(I, i), N))
27912791

2792+
# issue #9053
2793+
if Sys.iswindows()
2794+
function Filesystem.tempname(uunique::UInt32)
2795+
error("`tempname(::UInt32)` is discontinued.")
2796+
end
2797+
end
2798+
27922799
# END 0.7 deprecations
27932800

27942801
# BEGIN 1.0 deprecations

base/file.jl

Lines changed: 27 additions & 5 deletions
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

Lines changed: 5 additions & 11 deletions
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

Lines changed: 4 additions & 4 deletions
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")

test/replcompletions.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ end
776776

777777
if Sys.iswindows()
778778
tmp = tempname()
779+
touch(tmp)
779780
path = dirname(tmp)
780781
file = basename(tmp)
781782
temp_name = basename(path)

0 commit comments

Comments
 (0)