Skip to content

Commit cc96d40

Browse files
authored
Merge pull request #76 from apple/lorentey/post-back-ios15-system
Update package with changes from recent ABI stable releases
2 parents 9cdaaa3 + e9886bf commit cc96d40

21 files changed

+587
-45
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_library(SystemPackage
1717
PlatformString.swift
1818
SystemString.swift
1919
Util.swift
20+
Util+StringArray.swift
2021
UtilConsumers.swift)
2122
set_target_properties(SystemPackage PROPERTIES
2223
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
@@ -29,10 +30,12 @@ target_sources(SystemPackage PRIVATE
2930
FilePath/FilePathSyntax.swift
3031
FilePath/FilePathWindows.swift)
3132
target_sources(SystemPackage PRIVATE
33+
Internals/Backcompat.swift
3234
Internals/CInterop.swift
3335
Internals/Constants.swift
3436
Internals/Exports.swift
3537
Internals/Mocking.swift
38+
Internals/RawBuffer.swift
3639
Internals/Syscalls.swift
3740
Internals/WindowsSyscallAdapters.swift)
3841
target_link_libraries(SystemPackage PUBLIC

Sources/System/FileDescriptor.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
2930
extension FileDescriptor {
3031
/// The standard input file descriptor, with a numeric value of 0.
3132
@_alwaysEmitIntoClient

Sources/System/FileOperations.swift

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
373+
extension FileDescriptor {
312374
/// Duplicate this file descriptor and return the newly created copy.
313375
///
314376
/// - Parameters:
@@ -385,7 +447,7 @@ extension FileDescriptor {
385447
public static func pipe() throws -> (readEnd: FileDescriptor, writeEnd: FileDescriptor) {
386448
try _pipe().get()
387449
}
388-
450+
389451
/*System 1.1.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
390452
@usableFromInline
391453
internal static func _pipe() -> Result<(readEnd: FileDescriptor, writeEnd: FileDescriptor), Errno> {

Sources/System/FilePath/FilePathComponentView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extension FilePath {
3939
}
4040
}
4141

42-
#if SYSTEM_PACKAGE
42+
#if SYSTEM_PACKAGE // Workaround for a __consuming getter bug in Swift 5.3.3
4343
/// View the non-root components that make up this path.
4444
public var components: ComponentView {
4545
get { ComponentView(self) }
@@ -201,6 +201,7 @@ extension FilePath {
201201

202202
// MARK: - Internals
203203

204+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
204205
extension FilePath.ComponentView: _PathSlice {
205206
internal var _range: Range<SystemString.Index> {
206207
_start ..< _path._storage.endIndex
@@ -213,6 +214,7 @@ extension FilePath.ComponentView: _PathSlice {
213214

214215
// MARK: - Invariants
215216

217+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
216218
extension FilePath.ComponentView {
217219
internal func _invariantCheck() {
218220
#if DEBUG

Sources/System/FilePath/FilePathComponents.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ extension FilePath.Component {
9797
}
9898
}
9999

100+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
100101
extension FilePath.Root {
101102
// TODO: Windows analysis APIs
102103
}
@@ -182,15 +183,18 @@ extension _PathSlice {
182183
internal var _storage: SystemString { _path._storage }
183184
}
184185

186+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
185187
extension FilePath.Component: _PathSlice {
186188
}
189+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
187190
extension FilePath.Root: _PathSlice {
188191
internal var _range: Range<SystemString.Index> {
189192
(..<_rootEnd).relative(to: _path._storage)
190193
}
191194
}
195+
196+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
192197
extension FilePath: _PlatformStringable {
193-
@usableFromInline
194198
func _withPlatformString<Result>(_ body: (UnsafePointer<CInterop.PlatformChar>) throws -> Result) rethrows -> Result {
195199
try _storage.withPlatformString(body)
196200
}
@@ -201,6 +205,7 @@ extension FilePath: _PlatformStringable {
201205

202206
}
203207

208+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
204209
extension FilePath.Component {
205210
// The index of the `.` denoting an extension
206211
internal func _extensionIndex() -> SystemString.Index? {
@@ -229,6 +234,7 @@ internal func _makeExtension(_ ext: String) -> SystemString {
229234
return result
230235
}
231236

237+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
232238
extension FilePath.Component {
233239
internal init?(_ str: SystemString) {
234240
// FIXME: explicit null root? Or something else?
@@ -241,6 +247,7 @@ extension FilePath.Component {
241247
}
242248
}
243249

250+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
244251
extension FilePath.Root {
245252
internal init?(_ str: SystemString) {
246253
// FIXME: explicit null root? Or something else?
@@ -255,6 +262,7 @@ extension FilePath.Root {
255262

256263
// MARK: - Invariants
257264

265+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
258266
extension FilePath.Component {
259267
// TODO: ensure this all gets easily optimized away in release...
260268
internal func _invariantCheck() {
@@ -266,6 +274,8 @@ extension FilePath.Component {
266274
#endif // DEBUG
267275
}
268276
}
277+
278+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
269279
extension FilePath.Root {
270280
internal func _invariantCheck() {
271281
#if DEBUG

Sources/System/FilePath/FilePathParsing.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ extension SystemString {
111111
}
112112
}
113113

114+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
114115
extension FilePath {
115116
internal mutating func _removeTrailingSeparator() {
116117
_storage._removeTrailingSeparator()
@@ -191,6 +192,7 @@ extension SystemString {
191192
}
192193
}
193194

195+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
194196
extension FilePath {
195197
internal var _relativeStart: SystemString.Index {
196198
_storage._relativePathStart
@@ -202,6 +204,7 @@ extension FilePath {
202204

203205
// Parse separators
204206

207+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
205208
extension FilePath {
206209
internal typealias _Index = SystemString.Index
207210

@@ -265,6 +268,7 @@ extension FilePath {
265268
}
266269
}
267270

271+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
268272
extension FilePath.ComponentView {
269273
// TODO: Store this...
270274
internal var _relativeStart: SystemString.Index {
@@ -289,6 +293,7 @@ extension SystemString {
289293
}
290294
}
291295

296+
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
292297
extension FilePath.Root {
293298
// Asserting self is a root, returns whether this is an
294299
// absolute root.
@@ -313,6 +318,7 @@ extension FilePath.Root {
313318
}
314319
}
315320

321+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
316322
extension FilePath {
317323
internal var _portableDescription: String {
318324
guard _windowsPaths else { return description }
@@ -331,6 +337,7 @@ internal var _windowsPaths: Bool {
331337
#endif
332338
}
333339

340+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
334341
extension FilePath {
335342
// Whether we should add a separator when doing an append
336343
internal var _needsSeparatorForAppend: Bool {
@@ -358,6 +365,7 @@ extension FilePath {
358365
}
359366

360367
// MARK: - Invariants
368+
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
361369
extension FilePath {
362370
internal func _invariantCheck() {
363371
#if DEBUG

Sources/System/FilePath/FilePathString.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ extension FilePath {
6363
}
6464
}
6565

66+
#if !os(Windows)
67+
// Note: This function should have been opaque, but it shipped as
68+
// `@_alwaysEmitIntoClient` in macOS 12/iOS 15, and now it is stuck
69+
// this way forever. (Or until the language provides a way for us
70+
// to declare separate availability for a function's exported symbol
71+
// and its inlinable body.)
72+
6673
/// Calls the given closure with a pointer to the contents of the file path,
6774
/// represented as a null-terminated platform string.
6875
///
@@ -79,13 +86,27 @@ extension FilePath {
7986
public func withPlatformString<Result>(
8087
_ body: (UnsafePointer<CInterop.PlatformChar>) throws -> Result
8188
) rethrows -> Result {
82-
// For backwards deployment, call withCString if available.
83-
#if !os(Windows)
8489
return try withCString(body)
85-
#else
90+
}
91+
#else
92+
/// Calls the given closure with a pointer to the contents of the file path,
93+
/// represented as a null-terminated platform string.
94+
///
95+
/// - Parameter body: A closure with a pointer parameter
96+
/// that points to a null-terminated platform string.
97+
/// If `body` has a return value,
98+
/// that value is also used as the return value for this method.
99+
/// - Returns: The return value, if any, of the `body` closure parameter.
100+
///
101+
/// The pointer passed as an argument to `body` is valid
102+
/// only during the execution of this method.
103+
/// Don't try to store the pointer for later use.
104+
public func withPlatformString<Result>(
105+
_ body: (UnsafePointer<CInterop.PlatformChar>) throws -> Result
106+
) rethrows -> Result {
86107
return try _withPlatformString(body)
87-
#endif
88108
}
109+
#endif
89110
}
90111

91112
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/

Sources/System/FilePermissions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
public struct FilePermissions: OptionSet, Hashable, Codable {
2222
/// The raw C file permissions.
2323
@_alwaysEmitIntoClient
24-
public let rawValue: CInterop.Mode
24+
public let rawValue: CModeT
2525

2626
/// Create a strongly-typed file permission from a raw C value.
2727
@_alwaysEmitIntoClient
28-
public init(rawValue: CInterop.Mode) { self.rawValue = rawValue }
28+
public init(rawValue: CModeT) { self.rawValue = rawValue }
2929

3030
@_alwaysEmitIntoClient
31-
private init(_ raw: CInterop.Mode) { self.init(rawValue: raw) }
31+
private init(_ raw: CModeT) { self.init(rawValue: raw) }
3232

3333
/// Indicates that other users have read-only permission.
3434
@_alwaysEmitIntoClient
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
This source file is part of the Swift System open source project
3+
4+
Copyright (c) 2021 Apple Inc. and the Swift System project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
*/
9+
10+
extension String {
11+
internal init(
12+
_unsafeUninitializedCapacity capacity: Int,
13+
initializingUTF8With body: (UnsafeMutableBufferPointer<UInt8>) throws -> Int
14+
) rethrows {
15+
if #available(macOS 11, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
16+
self = try String(
17+
unsafeUninitializedCapacity: capacity,
18+
initializingUTF8With: body)
19+
return
20+
}
21+
22+
let array = try Array<UInt8>(
23+
unsafeUninitializedCapacity: capacity
24+
) { buffer, count in
25+
count = try body(buffer)
26+
}
27+
self = String(decoding: array, as: UTF8.self)
28+
}
29+
}

0 commit comments

Comments
 (0)