@@ -462,36 +462,22 @@ extension String {
462
462
return normalizedPath ( with: String ( decodingCString: wszPath, as: UTF16 . self) . standardizingPath)
463
463
#else
464
464
#if canImport(Darwin)
465
- let safe_confstr = { ( name: Int32 , buf: UnsafeMutablePointer < UInt8 > ? , len: Int ) -> Int in
466
- // POSIX moment of weird: confstr() is one of those annoying APIs which
467
- // can return zero for both error and non-error conditions, so the only
468
- // way to disambiguate is to put errno in a known state before calling.
469
- errno = 0
470
- let result = confstr ( name, buf, len)
471
-
472
- // result == 0 is only error if errno is not zero. But, if there was an
473
- // error, bail; all possible errors from confstr() are Very Bad Things.
474
- let err = errno // only read errno once in the failure case.
475
- precondition ( result > 0 || err == 0 , " Unexpected confstr() error: \( err) " )
476
-
477
- // This is extreme paranoia and should never happen; this would mean
478
- // confstr() returned < 0, which would only happen for impossibly long
479
- // sizes of value or long-dead versions of the OS.
480
- assert ( result >= 0 , " confstr() returned impossible result: \( result) " )
481
-
482
- return result
483
- }
484
-
485
- let length : Int = safe_confstr ( _CS_DARWIN_USER_TEMP_DIR, nil , 0 )
465
+ // If confstr returns 0 it either failed or the variable had no content
466
+ // If the variable had no content, we should continue on below
467
+ // If it fails, we should also silently ignore the error and continue on below. This API can fail for non-programmer reasons such as the device being out of storage space when libSystem attempts to create the directory
468
+ let length : Int = confstr ( _CS_DARWIN_USER_TEMP_DIR, nil , 0 )
486
469
if length > 0 {
487
- var buffer : [ UInt8 ] = . init( repeating: 0 , count: length)
488
- let final_length = safe_confstr ( _CS_DARWIN_USER_TEMP_DIR, & buffer, buffer. count)
489
-
490
- assert ( length == final_length, " Value of _CS_DARWIN_USER_TEMP_DIR changed? " )
491
- if length > 0 && length < buffer. count {
492
- return buffer. withUnsafeBufferPointer { b in
493
- String ( bytes: b, encoding: . utf8) !
470
+ let result : String ? = withUnsafeTemporaryAllocation ( of: UInt8 . self, capacity: length) { buffer in
471
+ let finalLength = confstr ( _CS_DARWIN_USER_TEMP_DIR, buffer. baseAddress!, buffer. count)
472
+ assert ( length == finalLength, " Value of _CS_DARWIN_USER_TEMP_DIR changed? " )
473
+ if length > 0 && length < buffer. count {
474
+ return String ( decoding: buffer, as: UTF8 . self)
494
475
}
476
+ return nil
477
+ }
478
+
479
+ if let result {
480
+ return result
495
481
}
496
482
}
497
483
#endif
0 commit comments