Skip to content

Commit

Permalink
make tempname on windows match unix behavior. fixes #9053
Browse files Browse the repository at this point in the history
also deprecate `tempname(::UInt32)` and add a warning to the docs.
  • Loading branch information
JeffBezanson committed Jan 14, 2018
1 parent a1ff12c commit 8d4e2a6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ This section lists changes that do not have deprecation warnings.
to get the old behavior (only "space" characters are considered as
word separators), use the keyword `wordsep=isspace`.

* The `tempname` function used to create a file on Windows but not on other
platforms. It now never creates a file ([#9053]).

Library improvements
--------------------

Expand Down
7 changes: 7 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2772,6 +2772,13 @@ end

@deprecate findin(a, b) find(occursin(b), a)

# issue #9053

if Sys.iswindows()
function Filesystem.tempname(uunique::UInt32)
error("`tempname(::UInt32)` is discontinued.")
end
end

# END 0.7 deprecations

Expand Down
32 changes: 27 additions & 5 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ function tempdir()
resize!(temppath,lentemppath)
return transcode(String, temppath)
end
tempname(uunique::UInt32=UInt32(0)) = tempname(tempdir(), uunique)

const temp_prefix = cwstring("jl_")
function tempname(temppath::AbstractString,uunique::UInt32)
function _win_tempname(temppath::AbstractString, uunique::UInt32)
tempp = cwstring(temppath)
tname = Vector{UInt16}(uninitialized, 32767)
uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname)
Expand All @@ -280,7 +280,7 @@ function tempname(temppath::AbstractString,uunique::UInt32)
end

function mktemp(parent=tempdir())
filename = tempname(parent, UInt32(0))
filename = _win_tempname(parent, UInt32(0))
return (filename, Base.open(filename, "r+"))
end

Expand All @@ -290,7 +290,7 @@ function mktempdir(parent=tempdir())
if (seed & typemax(UInt16)) == 0
seed += 1
end
filename = tempname(parent, seed)
filename = _win_tempname(parent, seed)
ret = ccall(:_wmkdir, Int32, (Ptr{UInt16},), cwstring(filename))
if ret == 0
return filename
Expand All @@ -300,6 +300,21 @@ function mktempdir(parent=tempdir())
end
end

function tempname()
parent = tempdir()
seed::UInt32 = rand(UInt32)
while true
if (seed & typemax(UInt16)) == 0
seed += 1
end
filename = _win_tempname(parent, seed)
if filemode(filename) == 0
return filename
end
seed += 1
end
end

else # !windows
# Obtain a temporary filename.
function tempname()
Expand Down Expand Up @@ -343,7 +358,14 @@ tempdir()
"""
tempname()
Generate a unique temporary file path.
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.
!!! warning
This can lead to race conditions if another process obtains the same
file name and creates the file before you are able to.
Using [`mktemp()`](@ref) is recommended instead.
"""
tempname()

Expand Down
16 changes: 5 additions & 11 deletions base/pkg/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -633,19 +633,13 @@ function build!(pkgs::Vector, seen::Set, errfile::AbstractString)
end

function build!(pkgs::Vector, errs::Dict, seen::Set=Set())
errfile = tempname()
touch(errfile) # create empty file
try
mktemp() do errfile, f
build!(pkgs, seen, errfile)
open(errfile, "r") do f
while !eof(f)
pkg = deserialize(f)
err = deserialize(f)
errs[pkg] = err
end
while !eof(f)
pkg = deserialize(f)
err = deserialize(f)
errs[pkg] = err
end
finally
isfile(errfile) && Base.rm(errfile)
end
end

Expand Down

0 comments on commit 8d4e2a6

Please sign in to comment.