@@ -735,7 +735,6 @@ public func NSFullUserName() -> String {
735735}
736736
737737internal func _NSCreateTemporaryFile( _ filePath: String ) throws -> ( Int32 , String ) {
738- let template = filePath + " .tmp.XXXXXX "
739738#if os(Windows)
740739 let maxLength : Int = Int ( MAX_PATH + 1 )
741740 var buf : [ UInt16 ] = Array < UInt16 > ( repeating: 0 , count: maxLength)
@@ -760,26 +759,32 @@ internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, Strin
760759 // Don't close h, fd is transferred ownership
761760 let fd = _open_osfhandle ( intptr_t ( bitPattern: h) , 0 )
762761#else
763- var filename = template. utf8CString
762+ var template = URL ( fileURLWithPath: filePath)
763+
764+ let filename = template. lastPathComponent
765+ let hashed = String ( format: " %llx " , Int64 ( filename. hashValue) )
766+ template. deleteLastPathComponent ( )
767+ template. appendPathComponent ( " SCF. \( hashed) .tmp.XXXXXX " )
764768
765- let result = filename. withUnsafeMutableBufferPointer { ( ptr: inout UnsafeMutableBufferPointer < CChar > ) -> ( Int32 , String ) ? in
766- // filename is updated with the temp file name on success.
767- let fd = mkstemp ( ptr. baseAddress!)
768- if fd == - 1 {
769- return nil
770- } else {
771- guard let fname = String ( utf8String: ptr. baseAddress!) else {
772- // Couldnt convert buffer back to filename.
773- close ( fd)
774- errno = ENOENT
775- return nil
776- }
777- return ( fd, fname)
778- }
769+
770+ let ( fd, errorCode, pathResult) = template. withUnsafeFileSystemRepresentation { ptr -> ( Int32 , Int32 , String ) in
771+ let length = strlen ( ptr!)
772+
773+ // buffer is updated with the temp file name on success.
774+ let buffer = UnsafeMutableBufferPointer< CChar> . allocate( capacity: length + 1 /* the null character */)
775+ UnsafeRawBufferPointer ( start: ptr!, count: length + 1 /* the null character */)
776+ . copyBytes ( to: UnsafeMutableRawBufferPointer ( buffer) )
777+ defer { buffer. deallocate ( ) }
778+
779+ let fd = mkstemp ( buffer. baseAddress!)
780+ let errorCode = errno
781+ return ( fd,
782+ errorCode,
783+ FileManager . default. string ( withFileSystemRepresentation: buffer. baseAddress!, length: strlen ( buffer. baseAddress!) ) )
779784 }
780785
781- guard let ( fd , pathResult ) = result else {
782- throw _NSErrorWithErrno ( errno , reading: false , path: template )
786+ if fd == - 1 {
787+ throw _NSErrorWithErrno ( errorCode , reading: false , path: pathResult )
783788 }
784789
785790 // Set the file mode to match macOS
@@ -802,8 +807,9 @@ internal func _NSCleanupTemporaryFile(_ auxFilePath: String, _ filePath: String)
802807 }
803808#else
804809 if rename ( $0, $1) != 0 {
810+ let errorCode = errno
805811 try ? FileManager . default. removeItem ( atPath: auxFilePath)
806- throw _NSErrorWithErrno ( errno , reading: false , path: filePath)
812+ throw _NSErrorWithErrno ( errorCode , reading: false , path: filePath)
807813 }
808814#endif
809815 } )
0 commit comments