@@ -748,7 +748,6 @@ public func NSFullUserName() -> String {
748748}
749749
750750internal func _NSCreateTemporaryFile( _ filePath: String ) throws -> ( Int32 , String ) {
751- let template = filePath + " .tmp.XXXXXX "
752751#if os(Windows)
753752 let maxLength : Int = Int ( MAX_PATH + 1 )
754753 var buf : [ UInt16 ] = Array < UInt16 > ( repeating: 0 , count: maxLength)
@@ -773,26 +772,32 @@ internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, Strin
773772 // Don't close h, fd is transferred ownership
774773 let fd = _open_osfhandle ( intptr_t ( bitPattern: h) , 0 )
775774#else
776- var filename = template. utf8CString
775+ var template = URL ( fileURLWithPath: filePath)
776+
777+ let filename = template. lastPathComponent
778+ let hashed = String ( format: " %llx " , Int64 ( filename. hashValue) )
779+ template. deleteLastPathComponent ( )
780+ template. appendPathComponent ( " SCF. \( hashed) .tmp.XXXXXX " )
777781
778- let result = filename. withUnsafeMutableBufferPointer { ( ptr: inout UnsafeMutableBufferPointer < CChar > ) -> ( Int32 , String ) ? in
779- // filename is updated with the temp file name on success.
780- let fd = mkstemp ( ptr. baseAddress!)
781- if fd == - 1 {
782- return nil
783- } else {
784- guard let fname = String ( utf8String: ptr. baseAddress!) else {
785- // Couldnt convert buffer back to filename.
786- close ( fd)
787- errno = ENOENT
788- return nil
789- }
790- return ( fd, fname)
791- }
782+
783+ let ( fd, errorCode, pathResult) = template. withUnsafeFileSystemRepresentation { ptr -> ( Int32 , Int32 , String ) in
784+ let length = strlen ( ptr!)
785+
786+ // buffer is updated with the temp file name on success.
787+ let buffer = UnsafeMutableBufferPointer< CChar> . allocate( capacity: length + 1 /* the null character */)
788+ UnsafeRawBufferPointer ( start: ptr!, count: length + 1 /* the null character */)
789+ . copyBytes ( to: UnsafeMutableRawBufferPointer ( buffer) )
790+ defer { buffer. deallocate ( ) }
791+
792+ let fd = mkstemp ( buffer. baseAddress!)
793+ let errorCode = errno
794+ return ( fd,
795+ errorCode,
796+ FileManager . default. string ( withFileSystemRepresentation: buffer. baseAddress!, length: strlen ( buffer. baseAddress!) ) )
792797 }
793798
794- guard let ( fd , pathResult ) = result else {
795- throw _NSErrorWithErrno ( errno , reading: false , path: template )
799+ if fd == - 1 {
800+ throw _NSErrorWithErrno ( errorCode , reading: false , path: pathResult )
796801 }
797802
798803 // Set the file mode to match macOS
@@ -815,8 +820,9 @@ internal func _NSCleanupTemporaryFile(_ auxFilePath: String, _ filePath: String)
815820 }
816821#else
817822 if rename ( $0, $1) != 0 {
823+ let errorCode = errno
818824 try ? FileManager . default. removeItem ( atPath: auxFilePath)
819- throw _NSErrorWithErrno ( errno , reading: false , path: filePath)
825+ throw _NSErrorWithErrno ( errorCode , reading: false , path: filePath)
820826 }
821827#endif
822828 } )
0 commit comments