@@ -416,24 +416,29 @@ function touch(path::AbstractString)
416416 path
417417end
418418
419+ const temp_prefix = " jl_"
420+
419421if Sys. iswindows ()
420422
421423function tempdir ()
422424 temppath = Vector {UInt16} (undef, 32767 )
423- lentemppath = ccall (:GetTempPathW ,stdcall,UInt32,(UInt32,Ptr{UInt16}),length (temppath),temppath)
425+ lentemppath = ccall (:GetTempPathW , stdcall, UInt32, (UInt32, Ptr{UInt16}), length (temppath), temppath)
424426 windowserror (" GetTempPath" , lentemppath >= length (temppath) || lentemppath == 0 )
425- resize! (temppath,lentemppath)
427+ resize! (temppath, lentemppath)
426428 return transcode (String, temppath)
427429end
428430
429- const temp_prefix = cwstring (" jl_" )
430431function _win_tempname (temppath:: AbstractString , uunique:: UInt32 )
431432 tempp = cwstring (temppath)
433+ temppfx = cwstring (temp_prefix)
432434 tname = Vector {UInt16} (undef, 32767 )
433- uunique = ccall (:GetTempFileNameW ,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname)
434- lentname = something (findfirst (iszero,tname), 0 )- 1
435- windowserror (" GetTempFileName" , uunique == 0 || lentname <= 0 )
436- resize! (tname,lentname)
435+ uunique = ccall (:GetTempFileNameW , stdcall, UInt32,
436+ (Ptr{UInt16}, Ptr{UInt16}, UInt32, Ptr{UInt16}),
437+ tempp, temppfx, uunique, tname)
438+ windowserror (" GetTempFileName" , uunique == 0 )
439+ lentname = something (findfirst (iszero, tname))
440+ @assert lentname > 0
441+ resize! (tname, lentname - 1 )
437442 return transcode (String, tname)
438443end
439444
@@ -442,22 +447,6 @@ function mktemp(parent=tempdir())
442447 return (filename, Base. open (filename, " r+" ))
443448end
444449
445- function mktempdir (parent= tempdir ())
446- seed:: UInt32 = Libc. rand (UInt32)
447- while true
448- if (seed & typemax (UInt16)) == 0
449- seed += 1
450- end
451- filename = _win_tempname (parent, seed)
452- ret = ccall (:_wmkdir , Int32, (Ptr{UInt16},), cwstring (filename))
453- if ret == 0
454- return filename
455- end
456- systemerror (:mktempdir , Libc. errno ()!= Libc. EEXIST)
457- seed += 1
458- end
459- end
460-
461450function tempname ()
462451 parent = tempdir ()
463452 seed:: UInt32 = rand (UInt32)
@@ -477,7 +466,7 @@ else # !windows
477466# Obtain a temporary filename.
478467function tempname ()
479468 d = get (ENV , " TMPDIR" , C_NULL ) # tempnam ignores TMPDIR on darwin
480- p = ccall (:tempnam , Cstring, (Cstring,Cstring), d, :julia )
469+ p = ccall (:tempnam , Cstring, (Cstring, Cstring), d, temp_prefix )
481470 systemerror (:tempnam , p == C_NULL )
482471 s = unsafe_string (p)
483472 Libc. free (p)
@@ -489,19 +478,12 @@ tempdir() = dirname(tempname())
489478
490479# Create and return the name of a temporary file along with an IOStream
491480function mktemp (parent= tempdir ())
492- b = joinpath (parent, " tmpXXXXXX " )
481+ b = joinpath (parent, temp_prefix * " XXXXXX " )
493482 p = ccall (:mkstemp , Int32, (Cstring,), b) # modifies b
494483 systemerror (:mktemp , p == - 1 )
495484 return (b, fdio (p, true ))
496485end
497486
498- # Create and return the name of a temporary directory
499- function mktempdir (parent= tempdir ())
500- b = joinpath (parent, " tmpXXXXXX" )
501- p = ccall (:mkdtemp , Cstring, (Cstring,), b)
502- systemerror (:mktempdir , p == C_NULL )
503- return unsafe_string (p)
504- end
505487
506488end # os-test
507489
@@ -536,12 +518,37 @@ is an open file object for this path.
536518mktemp (parent)
537519
538520"""
539- mktempdir(parent=tempdir())
521+ mktempdir(parent=tempdir(); prefix= $( repr (temp_prefix)) )
540522
541- Create a temporary directory in the `parent` directory and return its path.
523+ Create a temporary directory in the `parent` directory with a name
524+ constructed from the given prefix and a random suffix, and return its path.
525+ Additionally, any trailing `X` characters may be replaced with random characters.
542526If `parent` does not exist, throw an error.
543527"""
544- mktempdir (parent)
528+ function mktempdir (parent= tempdir (); prefix= temp_prefix)
529+ if isempty (parent) || occursin (path_separator_re, parent[end : end ])
530+ # append a path_separator only if parent didn't already have one
531+ tpath = " $(parent)$(prefix) XXXXXX"
532+ else
533+ tpath = " $(parent)$(path_separator)$(prefix) XXXXXX"
534+ end
535+
536+ req = Libc. malloc (_sizeof_uv_fs)
537+ try
538+ ret = ccall (:uv_fs_mkdtemp , Int32,
539+ (Ptr{Cvoid}, Ptr{Cvoid}, Cstring, Ptr{Cvoid}),
540+ eventloop (), req, tpath, C_NULL )
541+ if ret < 0
542+ ccall (:uv_fs_req_cleanup , Cvoid, (Ptr{Cvoid},), req)
543+ uv_error (" mktempdir" , ret)
544+ end
545+ path = unsafe_string (ccall (:jl_uv_fs_t_path , Cstring, (Ptr{Cvoid},), req))
546+ ccall (:uv_fs_req_cleanup , Cvoid, (Ptr{Cvoid},), req)
547+ return path
548+ finally
549+ Libc. free (req)
550+ end
551+ end
545552
546553
547554"""
@@ -566,13 +573,13 @@ function mktemp(fn::Function, parent=tempdir())
566573end
567574
568575"""
569- mktempdir(f::Function, parent=tempdir())
576+ mktempdir(f::Function, parent=tempdir(); prefix= $( repr (temp_prefix)) )
570577
571- Apply the function `f` to the result of [`mktempdir(parent)`](@ref) and remove the
572- temporary directory upon completion.
578+ Apply the function `f` to the result of [`mktempdir(parent; prefix )`](@ref) and remove the
579+ temporary directory all of its contents upon completion.
573580"""
574- function mktempdir (fn:: Function , parent= tempdir ())
575- tmpdir = mktempdir (parent)
581+ function mktempdir (fn:: Function , parent= tempdir (); prefix = temp_prefix )
582+ tmpdir = mktempdir (parent; prefix = prefix )
576583 try
577584 fn (tmpdir)
578585 finally
@@ -809,7 +816,7 @@ function readlink(path::AbstractString)
809816 uv_error (" readlink" , ret)
810817 @assert false
811818 end
812- tgt = unsafe_string (ccall (:jl_uv_fs_t_ptr , Ptr{Cchar} , (Ptr{Cvoid},), req))
819+ tgt = unsafe_string (ccall (:jl_uv_fs_t_ptr , Cstring , (Ptr{Cvoid},), req))
813820 ccall (:uv_fs_req_cleanup , Cvoid, (Ptr{Cvoid},), req)
814821 return tgt
815822 finally
0 commit comments