77 See https://swift.org/LICENSE.txt for license information
88*/
99
10- /*System 0.0.1, @available( macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
10+ @ available ( /*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8 , * )
1111extension FileDescriptor {
1212 /// Opens or creates a file for reading or writing.
1313 ///
@@ -31,12 +31,70 @@ extension FileDescriptor {
3131 permissions: FilePermissions ? = nil ,
3232 retryOnInterrupt: Bool = true
3333 ) throws -> FileDescriptor {
34- try path. withPlatformString {
34+ #if !os(Windows)
35+ return try path. withCString {
3536 try FileDescriptor . open (
3637 $0, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt)
3738 }
39+ #else
40+ return try path. withPlatformString {
41+ try FileDescriptor . open (
42+ $0, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt)
43+ }
44+ #endif
45+ }
46+
47+ #if !os(Windows)
48+ // On Darwin, `CInterop.PlatformChar` is less available than
49+ // `FileDescriptor.open`, so we need to use `CChar` instead.
50+
51+ /// Opens or creates a file for reading or writing.
52+ ///
53+ /// - Parameters:
54+ /// - path: The location of the file to open.
55+ /// - mode: The read and write access to use.
56+ /// - options: The behavior for opening the file.
57+ /// - permissions: The file permissions to use for created files.
58+ /// - retryOnInterrupt: Whether to retry the open operation
59+ /// if it throws ``Errno/interrupted``.
60+ /// The default is `true`.
61+ /// Pass `false` to try only once and throw an error upon interruption.
62+ /// - Returns: A file descriptor for the open file
63+ ///
64+ /// The corresponding C function is `open`.
65+ @_alwaysEmitIntoClient
66+ public static func open(
67+ _ path: UnsafePointer < CChar > ,
68+ _ mode: FileDescriptor . AccessMode ,
69+ options: FileDescriptor . OpenOptions = FileDescriptor . OpenOptions ( ) ,
70+ permissions: FilePermissions ? = nil ,
71+ retryOnInterrupt: Bool = true
72+ ) throws -> FileDescriptor {
73+ try FileDescriptor . _open (
74+ path, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt
75+ ) . get ( )
3876 }
3977
78+ @usableFromInline
79+ internal static func _open(
80+ _ path: UnsafePointer < CChar > ,
81+ _ mode: FileDescriptor . AccessMode ,
82+ options: FileDescriptor . OpenOptions ,
83+ permissions: FilePermissions ? ,
84+ retryOnInterrupt: Bool
85+ ) -> Result < FileDescriptor , Errno > {
86+ let oFlag = mode. rawValue | options. rawValue
87+ let descOrError : Result < CInt , Errno > = valueOrErrno ( retryOnInterrupt: retryOnInterrupt) {
88+ if let permissions = permissions {
89+ return system_open ( path, oFlag, permissions. rawValue)
90+ }
91+ precondition ( !options. contains ( . create) ,
92+ " Create must be given permissions " )
93+ return system_open ( path, oFlag)
94+ }
95+ return descOrError. map { FileDescriptor ( rawValue: $0) }
96+ }
97+ #else
4098 /// Opens or creates a file for reading or writing.
4199 ///
42100 /// - Parameters:
@@ -83,6 +141,7 @@ extension FileDescriptor {
83141 }
84142 return descOrError. map { FileDescriptor ( rawValue: $0) }
85143 }
144+ #endif
86145
87146 /// Deletes a file descriptor.
88147 ///
@@ -308,7 +367,10 @@ extension FileDescriptor {
308367 buffer,
309368 retryOnInterrupt: retryOnInterrupt)
310369 }
370+ }
311371
372+ @available ( /*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8 , * )
373+ extension FileDescriptor {
312374 /// Duplicate this file descriptor and return the newly created copy.
313375 ///
314376 /// - Parameters:
@@ -337,15 +399,15 @@ extension FileDescriptor {
337399 ///
338400 /// The corresponding C functions are `dup` and `dup2`.
339401 @_alwaysEmitIntoClient
340- /*System 0.0.2, @available( macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
402+ @ available ( /*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8 , * )
341403 public func duplicate(
342404 as target: FileDescriptor ? = nil ,
343405 retryOnInterrupt: Bool = true
344406 ) throws -> FileDescriptor {
345407 try _duplicate ( as: target, retryOnInterrupt: retryOnInterrupt) . get ( )
346408 }
347409
348- /*System 0.0.2, @available( macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
410+ @ available ( /*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8 , * )
349411 @usableFromInline
350412 internal func _duplicate(
351413 as target: FileDescriptor ? ,
@@ -373,20 +435,20 @@ extension FileDescriptor {
373435}
374436
375437#if !os(Windows)
376- /*System 1.1.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
438+ @ available ( /*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
377439extension FileDescriptor {
378440 /// Create a pipe, a unidirectional data channel which can be used for interprocess communication.
379441 ///
380442 /// - Returns: The pair of file descriptors.
381443 ///
382444 /// The corresponding C function is `pipe`.
383445 @_alwaysEmitIntoClient
384- /*System 1.1.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
446+ @ available ( /*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
385447 public static func pipe( ) throws -> ( readEnd: FileDescriptor , writeEnd: FileDescriptor ) {
386448 try _pipe ( ) . get ( )
387449 }
388-
389- /*System 1.1.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
450+
451+ @ available ( /*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
390452 @usableFromInline
391453 internal static func _pipe( ) -> Result < ( readEnd: FileDescriptor , writeEnd: FileDescriptor ) , Errno > {
392454 var fds : ( Int32 , Int32 ) = ( - 1 , - 1 )
@@ -402,7 +464,7 @@ extension FileDescriptor {
402464#endif
403465
404466#if !os(Windows)
405- /*System 1.2.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
467+ @ available ( /*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
406468extension FileDescriptor {
407469 /// Truncate or extend the file referenced by this file descriptor.
408470 ///
@@ -424,7 +486,7 @@ extension FileDescriptor {
424486 /// associated with the file.
425487 ///
426488 /// The corresponding C function is `ftruncate`.
427- /*System 1.2.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
489+ @ available ( /*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
428490 @_alwaysEmitIntoClient
429491 public func resize(
430492 to newSize: Int64 ,
@@ -436,7 +498,7 @@ extension FileDescriptor {
436498 ) . get ( )
437499 }
438500
439- /*System 1.2.0, @available( macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
501+ @ available ( /*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8 , * )
440502 @usableFromInline
441503 internal func _resize(
442504 to newSize: Int64 ,
0 commit comments