Skip to content

Commit 384b14d

Browse files
authored
Merge branch 'main' into files_of_a_feather_advisory_lock_together
2 parents a1cbeeb + f059b4b commit 384b14d

40 files changed

+1282
-189
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.DS_Store
22
/.build
33
/Packages
4-
/*.xcodeproj
4+
swift-system.xcodeproj
55
xcuserdata/
66
.*.sw?

Sources/System/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ add_library(SystemPackage
1313
FileHelpers.swift
1414
FileOperations.swift
1515
FilePermissions.swift
16+
MachPort.swift
1617
PlatformString.swift
1718
SystemString.swift
1819
Util.swift
20+
Util+StringArray.swift
1921
UtilConsumers.swift)
2022
set_target_properties(SystemPackage PROPERTIES
2123
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
@@ -28,10 +30,12 @@ target_sources(SystemPackage PRIVATE
2830
FilePath/FilePathSyntax.swift
2931
FilePath/FilePathWindows.swift)
3032
target_sources(SystemPackage PRIVATE
33+
Internals/Backcompat.swift
3134
Internals/CInterop.swift
3235
Internals/Constants.swift
3336
Internals/Exports.swift
3437
Internals/Mocking.swift
38+
Internals/RawBuffer.swift
3539
Internals/Syscalls.swift
3640
Internals/WindowsSyscallAdapters.swift)
3741
target_link_libraries(SystemPackage PUBLIC

Sources/System/Errno.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/// An error number used by system calls to communicate what kind of error
1111
/// occurred.
1212
@frozen
13-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
13+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
1414
public struct Errno: RawRepresentable, Error, Hashable, Codable {
1515
/// The raw C error number.
1616
@_alwaysEmitIntoClient
@@ -1274,6 +1274,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
12741274
@available(*, unavailable, renamed: "badMessage")
12751275
public static var EBADMSG: Errno { badMessage }
12761276

1277+
#if !os(OpenBSD)
12771278
/// Reserved.
12781279
///
12791280
/// This error is reserved for future use.
@@ -1333,6 +1334,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13331334
@_alwaysEmitIntoClient
13341335
@available(*, unavailable, renamed: "notStream")
13351336
public static var ENOSTR: Errno { notStream }
1337+
#endif
13361338

13371339
/// Protocol error.
13381340
///
@@ -1348,6 +1350,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13481350
@available(*, unavailable, renamed: "protocolError")
13491351
public static var EPROTO: Errno { protocolError }
13501352

1353+
#if !os(OpenBSD)
13511354
/// Reserved.
13521355
///
13531356
/// This error is reserved for future use.
@@ -1359,6 +1362,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13591362
@_alwaysEmitIntoClient
13601363
@available(*, unavailable, renamed: "timeout")
13611364
public static var ETIME: Errno { timeout }
1365+
#endif
13621366
#endif
13631367

13641368
/// Operation not supported on socket.
@@ -1376,7 +1380,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13761380
}
13771381

13781382
// Constants defined in header but not man page
1379-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
1383+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
13801384
extension Errno {
13811385

13821386
/// Operation would block.
@@ -1470,7 +1474,7 @@ extension Errno {
14701474
#endif
14711475
}
14721476

1473-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
1477+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
14741478
extension Errno {
14751479
// TODO: We want to provide safe access to `errno`, but we need a
14761480
// release-barrier to do so.
@@ -1485,14 +1489,14 @@ extension Errno {
14851489
}
14861490

14871491
// Use "hidden" entry points for `NSError` bridging
1488-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
1492+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
14891493
extension Errno {
14901494
public var _code: Int { Int(rawValue) }
14911495

14921496
public var _domain: String { "NSPOSIXErrorDomain" }
14931497
}
14941498

1495-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
1499+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
14961500
extension Errno: CustomStringConvertible, CustomDebugStringConvertible {
14971501
/// A textual representation of the most recent error
14981502
/// returned by a system call.
@@ -1512,7 +1516,7 @@ extension Errno: CustomStringConvertible, CustomDebugStringConvertible {
15121516
public var debugDescription: String { self.description }
15131517
}
15141518

1515-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
1519+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
15161520
extension Errno {
15171521
@_alwaysEmitIntoClient
15181522
public static func ~=(_ lhs: Errno, _ rhs: Error) -> Bool {

Sources/System/FileDescriptor.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/// of `FileDescriptor` values,
1515
/// in the same way as you manage a raw C file handle.
1616
@frozen
17-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
17+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
1818
public struct FileDescriptor: RawRepresentable, Hashable, Codable {
1919
/// The raw C file handle.
2020
@_alwaysEmitIntoClient
@@ -25,7 +25,8 @@ public struct FileDescriptor: RawRepresentable, Hashable, Codable {
2525
public init(rawValue: CInt) { self.rawValue = rawValue }
2626
}
2727

28-
// Standard file descriptors
28+
// Standard file descriptors.
29+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
2930
extension FileDescriptor {
3031
/// The standard input file descriptor, with a numeric value of 0.
3132
@_alwaysEmitIntoClient
@@ -40,7 +41,7 @@ extension FileDescriptor {
4041
public static var standardError: FileDescriptor { .init(rawValue: 2) }
4142
}
4243

43-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
44+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
4445
extension FileDescriptor {
4546
/// The desired read and write access for a newly opened file.
4647
@frozen
@@ -385,7 +386,7 @@ extension FileDescriptor {
385386
}
386387
}
387388

388-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
389+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
389390
extension FileDescriptor.AccessMode
390391
: CustomStringConvertible, CustomDebugStringConvertible
391392
{
@@ -404,7 +405,7 @@ extension FileDescriptor.AccessMode
404405
public var debugDescription: String { self.description }
405406
}
406407

407-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
408+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
408409
extension FileDescriptor.SeekOrigin
409410
: CustomStringConvertible, CustomDebugStringConvertible
410411
{
@@ -427,7 +428,7 @@ extension FileDescriptor.SeekOrigin
427428
public var debugDescription: String { self.description }
428429
}
429430

430-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
431+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
431432
extension FileDescriptor.OpenOptions
432433
: CustomStringConvertible, CustomDebugStringConvertible
433434
{
@@ -473,3 +474,14 @@ extension FileDescriptor.OpenOptions
473474
/// A textual representation of the open options, suitable for debugging.
474475
public var debugDescription: String { self.description }
475476
}
477+
478+
#if compiler(>=5.5) && canImport(_Concurrency)
479+
// The decision on whether to make FileDescriptor Sendable or not
480+
// is currently being discussed in https://github.com/apple/swift-system/pull/112
481+
//@available(*, unavailable, message: "File descriptors are not completely thread-safe.")
482+
//extension FileDescriptor: Sendable {}
483+
484+
extension FileDescriptor.AccessMode: Sendable {}
485+
extension FileDescriptor.OpenOptions: Sendable {}
486+
extension FileDescriptor.SeekOrigin: Sendable {}
487+
#endif

Sources/System/FileHelpers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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, *)
1111
extension FileDescriptor {
1212
/// Runs a closure and then closes the file descriptor, even if an error occurs.
1313
///

Sources/System/FileOperations.swift

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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, *)
1111
extension 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, *)
377439
extension 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, *)
406468
extension 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,

Sources/System/FilePath/FilePath.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@
3737
/// However, the rules for path equivalence
3838
/// are file-system–specific and have additional considerations
3939
/// like case insensitivity, Unicode normalization, and symbolic links.
40-
///
41-
// TODO(docs): Section on all the new syntactic operations, lexical normalization, decomposition,
42-
// components, etc.
43-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
40+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
4441
public struct FilePath {
42+
// TODO(docs): Section on all the new syntactic operations, lexical normalization, decomposition,
43+
// components, etc.
4544
internal var _storage: SystemString
4645

4746
/// Creates an empty, null-terminated path.
@@ -60,12 +59,15 @@ public struct FilePath {
6059
}
6160
}
6261

63-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
62+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
6463
extension FilePath {
6564
/// The length of the file path, excluding the null terminator.
6665
public var length: Int { _storage.length }
6766
}
6867

69-
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
68+
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
7069
extension FilePath: Hashable, Codable {}
7170

71+
#if compiler(>=5.5) && canImport(_Concurrency)
72+
extension FilePath: Sendable {}
73+
#endif

0 commit comments

Comments
 (0)