Skip to content

Commit

Permalink
Merge branch 'main' into files_of_a_feather_advisory_lock_together
Browse files Browse the repository at this point in the history
  • Loading branch information
milseman authored Mar 8, 2023
2 parents a1cbeeb + f059b4b commit 384b14d
Show file tree
Hide file tree
Showing 40 changed files with 1,282 additions and 189 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
swift-system.xcodeproj
xcuserdata/
.*.sw?
4 changes: 4 additions & 0 deletions Sources/System/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ add_library(SystemPackage
FileHelpers.swift
FileOperations.swift
FilePermissions.swift
MachPort.swift
PlatformString.swift
SystemString.swift
Util.swift
Util+StringArray.swift
UtilConsumers.swift)
set_target_properties(SystemPackage PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
Expand All @@ -28,10 +30,12 @@ target_sources(SystemPackage PRIVATE
FilePath/FilePathSyntax.swift
FilePath/FilePathWindows.swift)
target_sources(SystemPackage PRIVATE
Internals/Backcompat.swift
Internals/CInterop.swift
Internals/Constants.swift
Internals/Exports.swift
Internals/Mocking.swift
Internals/RawBuffer.swift
Internals/Syscalls.swift
Internals/WindowsSyscallAdapters.swift)
target_link_libraries(SystemPackage PUBLIC
Expand Down
16 changes: 10 additions & 6 deletions Sources/System/Errno.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/// An error number used by system calls to communicate what kind of error
/// occurred.
@frozen
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
public struct Errno: RawRepresentable, Error, Hashable, Codable {
/// The raw C error number.
@_alwaysEmitIntoClient
Expand Down Expand Up @@ -1274,6 +1274,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
@available(*, unavailable, renamed: "badMessage")
public static var EBADMSG: Errno { badMessage }

#if !os(OpenBSD)
/// Reserved.
///
/// This error is reserved for future use.
Expand Down Expand Up @@ -1333,6 +1334,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
@_alwaysEmitIntoClient
@available(*, unavailable, renamed: "notStream")
public static var ENOSTR: Errno { notStream }
#endif

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

#if !os(OpenBSD)
/// Reserved.
///
/// This error is reserved for future use.
Expand All @@ -1359,6 +1362,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
@_alwaysEmitIntoClient
@available(*, unavailable, renamed: "timeout")
public static var ETIME: Errno { timeout }
#endif
#endif

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

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

/// Operation would block.
Expand Down Expand Up @@ -1470,7 +1474,7 @@ extension Errno {
#endif
}

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

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

public var _domain: String { "NSPOSIXErrorDomain" }
}

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

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension Errno {
@_alwaysEmitIntoClient
public static func ~=(_ lhs: Errno, _ rhs: Error) -> Bool {
Expand Down
24 changes: 18 additions & 6 deletions Sources/System/FileDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/// of `FileDescriptor` values,
/// in the same way as you manage a raw C file handle.
@frozen
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
public struct FileDescriptor: RawRepresentable, Hashable, Codable {
/// The raw C file handle.
@_alwaysEmitIntoClient
Expand All @@ -25,7 +25,8 @@ public struct FileDescriptor: RawRepresentable, Hashable, Codable {
public init(rawValue: CInt) { self.rawValue = rawValue }
}

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

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor {
/// The desired read and write access for a newly opened file.
@frozen
Expand Down Expand Up @@ -385,7 +386,7 @@ extension FileDescriptor {
}
}

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor.AccessMode
: CustomStringConvertible, CustomDebugStringConvertible
{
Expand All @@ -404,7 +405,7 @@ extension FileDescriptor.AccessMode
public var debugDescription: String { self.description }
}

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor.SeekOrigin
: CustomStringConvertible, CustomDebugStringConvertible
{
Expand All @@ -427,7 +428,7 @@ extension FileDescriptor.SeekOrigin
public var debugDescription: String { self.description }
}

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor.OpenOptions
: CustomStringConvertible, CustomDebugStringConvertible
{
Expand Down Expand Up @@ -473,3 +474,14 @@ extension FileDescriptor.OpenOptions
/// A textual representation of the open options, suitable for debugging.
public var debugDescription: String { self.description }
}

#if compiler(>=5.5) && canImport(_Concurrency)
// The decision on whether to make FileDescriptor Sendable or not
// is currently being discussed in https://github.com/apple/swift-system/pull/112
//@available(*, unavailable, message: "File descriptors are not completely thread-safe.")
//extension FileDescriptor: Sendable {}

extension FileDescriptor.AccessMode: Sendable {}
extension FileDescriptor.OpenOptions: Sendable {}
extension FileDescriptor.SeekOrigin: Sendable {}
#endif
2 changes: 1 addition & 1 deletion Sources/System/FileHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
See https://swift.org/LICENSE.txt for license information
*/

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor {
/// Runs a closure and then closes the file descriptor, even if an error occurs.
///
Expand Down
84 changes: 73 additions & 11 deletions Sources/System/FileOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
See https://swift.org/LICENSE.txt for license information
*/

/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
extension FileDescriptor {
/// Opens or creates a file for reading or writing.
///
Expand All @@ -31,12 +31,70 @@ extension FileDescriptor {
permissions: FilePermissions? = nil,
retryOnInterrupt: Bool = true
) throws -> FileDescriptor {
try path.withPlatformString {
#if !os(Windows)
return try path.withCString {
try FileDescriptor.open(
$0, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt)
}
#else
return try path.withPlatformString {
try FileDescriptor.open(
$0, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt)
}
#endif
}

#if !os(Windows)
// On Darwin, `CInterop.PlatformChar` is less available than
// `FileDescriptor.open`, so we need to use `CChar` instead.

/// Opens or creates a file for reading or writing.
///
/// - Parameters:
/// - path: The location of the file to open.
/// - mode: The read and write access to use.
/// - options: The behavior for opening the file.
/// - permissions: The file permissions to use for created files.
/// - retryOnInterrupt: Whether to retry the open operation
/// if it throws ``Errno/interrupted``.
/// The default is `true`.
/// Pass `false` to try only once and throw an error upon interruption.
/// - Returns: A file descriptor for the open file
///
/// The corresponding C function is `open`.
@_alwaysEmitIntoClient
public static func open(
_ path: UnsafePointer<CChar>,
_ mode: FileDescriptor.AccessMode,
options: FileDescriptor.OpenOptions = FileDescriptor.OpenOptions(),
permissions: FilePermissions? = nil,
retryOnInterrupt: Bool = true
) throws -> FileDescriptor {
try FileDescriptor._open(
path, mode, options: options, permissions: permissions, retryOnInterrupt: retryOnInterrupt
).get()
}

@usableFromInline
internal static func _open(
_ path: UnsafePointer<CChar>,
_ mode: FileDescriptor.AccessMode,
options: FileDescriptor.OpenOptions,
permissions: FilePermissions?,
retryOnInterrupt: Bool
) -> Result<FileDescriptor, Errno> {
let oFlag = mode.rawValue | options.rawValue
let descOrError: Result<CInt, Errno> = valueOrErrno(retryOnInterrupt: retryOnInterrupt) {
if let permissions = permissions {
return system_open(path, oFlag, permissions.rawValue)
}
precondition(!options.contains(.create),
"Create must be given permissions")
return system_open(path, oFlag)
}
return descOrError.map { FileDescriptor(rawValue: $0) }
}
#else
/// Opens or creates a file for reading or writing.
///
/// - Parameters:
Expand Down Expand Up @@ -83,6 +141,7 @@ extension FileDescriptor {
}
return descOrError.map { FileDescriptor(rawValue: $0) }
}
#endif

/// Deletes a file descriptor.
///
Expand Down Expand Up @@ -308,7 +367,10 @@ extension FileDescriptor {
buffer,
retryOnInterrupt: retryOnInterrupt)
}
}

@available(/*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8, *)
extension FileDescriptor {
/// Duplicate this file descriptor and return the newly created copy.
///
/// - Parameters:
Expand Down Expand Up @@ -337,15 +399,15 @@ extension FileDescriptor {
///
/// The corresponding C functions are `dup` and `dup2`.
@_alwaysEmitIntoClient
/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
@available(/*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8, *)
public func duplicate(
as target: FileDescriptor? = nil,
retryOnInterrupt: Bool = true
) throws -> FileDescriptor {
try _duplicate(as: target, retryOnInterrupt: retryOnInterrupt).get()
}

/*System 0.0.2, @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)*/
@available(/*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8, *)
@usableFromInline
internal func _duplicate(
as target: FileDescriptor?,
Expand Down Expand Up @@ -373,20 +435,20 @@ extension FileDescriptor {
}

#if !os(Windows)
/*System 1.1.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
@available(/*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
extension FileDescriptor {
/// Create a pipe, a unidirectional data channel which can be used for interprocess communication.
///
/// - Returns: The pair of file descriptors.
///
/// The corresponding C function is `pipe`.
@_alwaysEmitIntoClient
/*System 1.1.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
@available(/*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
public static func pipe() throws -> (readEnd: FileDescriptor, writeEnd: FileDescriptor) {
try _pipe().get()
}
/*System 1.1.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/

@available(/*System 1.1.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
@usableFromInline
internal static func _pipe() -> Result<(readEnd: FileDescriptor, writeEnd: FileDescriptor), Errno> {
var fds: (Int32, Int32) = (-1, -1)
Expand All @@ -402,7 +464,7 @@ extension FileDescriptor {
#endif

#if !os(Windows)
/*System 1.2.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
@available(/*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
extension FileDescriptor {
/// Truncate or extend the file referenced by this file descriptor.
///
Expand All @@ -424,7 +486,7 @@ extension FileDescriptor {
/// associated with the file.
///
/// The corresponding C function is `ftruncate`.
/*System 1.2.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
@available(/*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
@_alwaysEmitIntoClient
public func resize(
to newSize: Int64,
Expand All @@ -436,7 +498,7 @@ extension FileDescriptor {
).get()
}

/*System 1.2.0, @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)*/
@available(/*System 1.2.0: macOS 9999, iOS 9999, watchOS 9999, tvOS 9999*/iOS 8, *)
@usableFromInline
internal func _resize(
to newSize: Int64,
Expand Down
14 changes: 8 additions & 6 deletions Sources/System/FilePath/FilePath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@
/// However, the rules for path equivalence
/// are file-system–specific and have additional considerations
/// like case insensitivity, Unicode normalization, and symbolic links.
///
// TODO(docs): Section on all the new syntactic operations, lexical normalization, decomposition,
// components, etc.
/*System 0.0.1, @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)*/
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
public struct FilePath {
// TODO(docs): Section on all the new syntactic operations, lexical normalization, decomposition,
// components, etc.
internal var _storage: SystemString

/// Creates an empty, null-terminated path.
Expand All @@ -60,12 +59,15 @@ public struct FilePath {
}
}

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

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

#if compiler(>=5.5) && canImport(_Concurrency)
extension FilePath: Sendable {}
#endif
Loading

0 comments on commit 384b14d

Please sign in to comment.