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 12, 2018
1 parent f8bc37b commit e551cec
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 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 @@ -2785,6 +2785,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
28 changes: 24 additions & 4 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,20 @@ function mktempdir(parent=tempdir())
end
end

function tempname()
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 @@ -344,6 +358,12 @@ tempdir()
tempname()
Generate a unique temporary file path.
!!! 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 e551cec

Please sign in to comment.