Skip to content

Commit b11b33a

Browse files
authored
Merge pull request #256 from jrflat/stat-implementation
Stat implementation for Swift System
2 parents d5f59fe + 55350cd commit b11b33a

File tree

12 files changed

+1872
-10
lines changed

12 files changed

+1872
-10
lines changed

Package.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ let availability: [Available] = [
6464
Available("1.5.0", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
6565
Available("1.6.0", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
6666
Available("1.6.1", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
67+
68+
Available("99", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
6769
]
6870

6971
let swiftSettingsAvailability = availability.map(\.swiftSetting)

Sources/System/Errno.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
961961

962962
/// Stale NFS file handle.
963963
///
964-
/// You attempted access an open file on an NFS filesystem,
964+
/// You attempted access an open file on an NFS file system,
965965
/// which is now unavailable as referenced by the given file descriptor.
966966
/// This may indicate that the file was deleted on the NFS server
967967
/// or that some other catastrophic event occurred.
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift System open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift System project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
// |------------------------|
13+
// | Swift API to C Mapping |
14+
// |------------------------------------------------------------------|
15+
// | FileFlags | Darwin | FreeBSD | OpenBSD |
16+
// |------------------|---------------|---------------|---------------|
17+
// | noDump | UF_NODUMP | UF_NODUMP | UF_NODUMP |
18+
// | userImmutable | UF_IMMUTABLE | UF_IMMUTABLE | UF_IMMUTABLE |
19+
// | userAppend | UF_APPEND | UF_APPEND | UF_APPEND |
20+
// | archived | SF_ARCHIVED | SF_ARCHIVED | SF_ARCHIVED |
21+
// | systemImmutable | SF_IMMUTABLE | SF_IMMUTABLE | SF_IMMUTABLE |
22+
// | systemAppend | SF_APPEND | SF_APPEND | SF_APPEND |
23+
// | opaque | UF_OPAQUE | UF_OPAQUE | N/A |
24+
// | hidden | UF_HIDDEN | UF_HIDDEN | N/A |
25+
// | systemNoUnlink | SF_NOUNLINK | SF_NOUNLINK | N/A |
26+
// | compressed | UF_COMPRESSED | N/A | N/A |
27+
// | tracked | UF_TRACKED | N/A | N/A |
28+
// | dataVault | UF_DATAVAULT | N/A | N/A |
29+
// | restricted | SF_RESTRICTED | N/A | N/A |
30+
// | firmlink | SF_FIRMLINK | N/A | N/A |
31+
// | dataless | SF_DATALESS | N/A | N/A |
32+
// | userNoUnlink | N/A | UF_NOUNLINK | N/A |
33+
// | offline | N/A | UF_OFFLINE | N/A |
34+
// | readOnly | N/A | UF_READONLY | N/A |
35+
// | reparse | N/A | UF_REPARSE | N/A |
36+
// | sparse | N/A | UF_SPARSE | N/A |
37+
// | system | N/A | UF_SYSTEM | N/A |
38+
// | snapshot | N/A | SF_SNAPSHOT | N/A |
39+
// |------------------|---------------|---------------|---------------|
40+
41+
#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD) || os(OpenBSD)
42+
43+
/// File-specific flags found in the `st_flags` property of a `stat` struct
44+
/// or used as input to `chflags()`.
45+
///
46+
/// - Note: Only available on Darwin, FreeBSD, and OpenBSD.
47+
@frozen
48+
@available(System 99, *)
49+
public struct FileFlags: OptionSet, Sendable, Hashable, Codable {
50+
51+
/// The raw C flags.
52+
@_alwaysEmitIntoClient
53+
public let rawValue: CInterop.FileFlags
54+
55+
/// Creates a strongly-typed `FileFlags` from the raw C value.
56+
@_alwaysEmitIntoClient
57+
public init(rawValue: CInterop.FileFlags) { self.rawValue = rawValue }
58+
59+
// MARK: Flags Available on Darwin, FreeBSD, and OpenBSD
60+
61+
/// Do not dump the file during backups.
62+
///
63+
/// The corresponding C constant is `UF_NODUMP`.
64+
/// - Note: This flag may be changed by the file owner or superuser.
65+
@_alwaysEmitIntoClient
66+
public static var noDump: FileFlags { FileFlags(rawValue: _UF_NODUMP) }
67+
68+
/// File may not be changed.
69+
///
70+
/// The corresponding C constant is `UF_IMMUTABLE`.
71+
/// - Note: This flag may be changed by the file owner or superuser.
72+
@_alwaysEmitIntoClient
73+
public static var userImmutable: FileFlags { FileFlags(rawValue: _UF_IMMUTABLE) }
74+
75+
/// Writes to the file may only append.
76+
///
77+
/// The corresponding C constant is `UF_APPEND`.
78+
/// - Note: This flag may be changed by the file owner or superuser.
79+
@_alwaysEmitIntoClient
80+
public static var userAppend: FileFlags { FileFlags(rawValue: _UF_APPEND) }
81+
82+
/// File has been archived.
83+
///
84+
/// The corresponding C constant is `SF_ARCHIVED`.
85+
/// - Note: This flag may only be changed by the superuser.
86+
@_alwaysEmitIntoClient
87+
public static var archived: FileFlags { FileFlags(rawValue: _SF_ARCHIVED) }
88+
89+
/// File may not be changed.
90+
///
91+
/// The corresponding C constant is `SF_IMMUTABLE`.
92+
/// - Note: This flag may only be changed by the superuser.
93+
@_alwaysEmitIntoClient
94+
public static var systemImmutable: FileFlags { FileFlags(rawValue: _SF_IMMUTABLE) }
95+
96+
/// Writes to the file may only append.
97+
///
98+
/// The corresponding C constant is `SF_APPEND`.
99+
/// - Note: This flag may only be changed by the superuser.
100+
@_alwaysEmitIntoClient
101+
public static var systemAppend: FileFlags { FileFlags(rawValue: _SF_APPEND) }
102+
103+
// MARK: Flags Available on Darwin and FreeBSD
104+
105+
#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD)
106+
/// Directory is opaque when viewed through a union mount.
107+
///
108+
/// The corresponding C constant is `UF_OPAQUE`.
109+
/// - Note: This flag may be changed by the file owner or superuser.
110+
@_alwaysEmitIntoClient
111+
public static var opaque: FileFlags { FileFlags(rawValue: _UF_OPAQUE) }
112+
113+
/// File should not be displayed in a GUI.
114+
///
115+
/// The corresponding C constant is `UF_HIDDEN`.
116+
/// - Note: This flag may be changed by the file owner or superuser.
117+
@_alwaysEmitIntoClient
118+
public static var hidden: FileFlags { FileFlags(rawValue: _UF_HIDDEN) }
119+
120+
/// File may not be removed or renamed.
121+
///
122+
/// The corresponding C constant is `SF_NOUNLINK`.
123+
/// - Note: This flag may only be changed by the superuser.
124+
@_alwaysEmitIntoClient
125+
public static var systemNoUnlink: FileFlags { FileFlags(rawValue: _SF_NOUNLINK) }
126+
#endif
127+
128+
// MARK: Flags Available on Darwin only
129+
130+
#if SYSTEM_PACKAGE_DARWIN
131+
/// File is compressed at the file system level.
132+
///
133+
/// The corresponding C constant is `UF_COMPRESSED`.
134+
/// - Note: This flag is read-only. Attempting to change it will result in undefined behavior.
135+
@_alwaysEmitIntoClient
136+
public static var compressed: FileFlags { FileFlags(rawValue: _UF_COMPRESSED) }
137+
138+
/// File is tracked for the purpose of document IDs.
139+
///
140+
/// The corresponding C constant is `UF_TRACKED`.
141+
/// - Note: This flag may be changed by the file owner or superuser.
142+
@_alwaysEmitIntoClient
143+
public static var tracked: FileFlags { FileFlags(rawValue: _UF_TRACKED) }
144+
145+
/// File requires an entitlement for reading and writing.
146+
///
147+
/// The corresponding C constant is `UF_DATAVAULT`.
148+
/// - Note: This flag may be changed by the file owner or superuser.
149+
@_alwaysEmitIntoClient
150+
public static var dataVault: FileFlags { FileFlags(rawValue: _UF_DATAVAULT) }
151+
152+
/// File requires an entitlement for writing.
153+
///
154+
/// The corresponding C constant is `SF_RESTRICTED`.
155+
/// - Note: This flag may only be changed by the superuser.
156+
@_alwaysEmitIntoClient
157+
public static var restricted: FileFlags { FileFlags(rawValue: _SF_RESTRICTED) }
158+
159+
/// File is a firmlink.
160+
///
161+
/// Firmlinks are used by macOS to create transparent links between
162+
/// the read-only system volume and writable data volume. For example,
163+
/// the `/Applications` folder on the system volume is a firmlink to
164+
/// the `/Applications` folder on the data volume, allowing the user
165+
/// to see both system- and user-installed applications in a single folder.
166+
///
167+
/// The corresponding C constant is `SF_FIRMLINK`.
168+
/// - Note: This flag may only be changed by the superuser.
169+
@_alwaysEmitIntoClient
170+
public static var firmlink: FileFlags { FileFlags(rawValue: _SF_FIRMLINK) }
171+
172+
/// File is a dataless placeholder (content is stored remotely).
173+
///
174+
/// The system will attempt to materialize the file when accessed according to
175+
/// the dataless file materialization policy of the accessing thread or process.
176+
/// See `getiopolicy_np(3)`.
177+
///
178+
/// The corresponding C constant is `SF_DATALESS`.
179+
/// - Note: This flag is read-only. Attempting to change it will result in undefined behavior.
180+
@_alwaysEmitIntoClient
181+
public static var dataless: FileFlags { FileFlags(rawValue: _SF_DATALESS) }
182+
#endif
183+
184+
// MARK: Flags Available on FreeBSD Only
185+
186+
#if os(FreeBSD)
187+
/// File may not be removed or renamed.
188+
///
189+
/// The corresponding C constant is `UF_NOUNLINK`.
190+
/// - Note: This flag may be changed by the file owner or superuser.
191+
@_alwaysEmitIntoClient
192+
public static var userNoUnlink: FileFlags { FileFlags(rawValue: _UF_NOUNLINK) }
193+
194+
/// File has the Windows offline attribute.
195+
///
196+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_OFFLINE` attribute,
197+
/// but otherwise provide no special handling when it's set.
198+
///
199+
/// The corresponding C constant is `UF_OFFLINE`.
200+
/// - Note: This flag may be changed by the file owner or superuser.
201+
@_alwaysEmitIntoClient
202+
public static var offline: FileFlags { FileFlags(rawValue: _UF_OFFLINE) }
203+
204+
/// File is read-only.
205+
///
206+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_READONLY` attribute.
207+
///
208+
/// The corresponding C constant is `UF_READONLY`.
209+
/// - Note: This flag may be changed by the file owner or superuser.
210+
@_alwaysEmitIntoClient
211+
public static var readOnly: FileFlags { FileFlags(rawValue: _UF_READONLY) }
212+
213+
/// File contains a Windows reparse point.
214+
///
215+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_REPARSE_POINT` attribute.
216+
///
217+
/// The corresponding C constant is `UF_REPARSE`.
218+
/// - Note: This flag may be changed by the file owner or superuser.
219+
@_alwaysEmitIntoClient
220+
public static var reparse: FileFlags { FileFlags(rawValue: _UF_REPARSE) }
221+
222+
/// File is sparse.
223+
///
224+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_SPARSE_FILE` attribute,
225+
/// or to indicate a sparse file.
226+
///
227+
/// The corresponding C constant is `UF_SPARSE`.
228+
/// - Note: This flag may be changed by the file owner or superuser.
229+
@_alwaysEmitIntoClient
230+
public static var sparse: FileFlags { FileFlags(rawValue: _UF_SPARSE) }
231+
232+
/// File has the Windows system attribute.
233+
///
234+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_SYSTEM` attribute,
235+
/// but otherwise provide no special handling when it's set.
236+
///
237+
/// The corresponding C constant is `UF_SYSTEM`.
238+
/// - Note: This flag may be changed by the file owner or superuser.
239+
@_alwaysEmitIntoClient
240+
public static var system: FileFlags { FileFlags(rawValue: _UF_SYSTEM) }
241+
242+
/// File is a snapshot.
243+
///
244+
/// The corresponding C constant is `SF_SNAPSHOT`.
245+
/// - Note: This flag may only be changed by the superuser.
246+
@_alwaysEmitIntoClient
247+
public static var snapshot: FileFlags { FileFlags(rawValue: _SF_SNAPSHOT) }
248+
#endif
249+
}
250+
#endif
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift System open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift System project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#if !os(Windows)
13+
/// A strongly-typed file mode representing a C `mode_t`.
14+
///
15+
/// - Note: Only available on Unix-like platforms.
16+
@frozen
17+
@available(System 99, *)
18+
public struct FileMode: RawRepresentable, Sendable, Hashable, Codable {
19+
20+
/// The raw C mode.
21+
@_alwaysEmitIntoClient
22+
public var rawValue: CInterop.Mode
23+
24+
/// Creates a strongly-typed `FileMode` from the raw C value.
25+
@_alwaysEmitIntoClient
26+
public init(rawValue: CInterop.Mode) { self.rawValue = rawValue }
27+
28+
/// Creates a `FileMode` from the given file type and permissions.
29+
///
30+
/// - Note: This initializer masks the inputs with their respective bit masks.
31+
@_alwaysEmitIntoClient
32+
public init(type: FileType, permissions: FilePermissions) {
33+
self.rawValue = (type.rawValue & _MODE_FILETYPE_MASK) | (permissions.rawValue & _MODE_PERMISSIONS_MASK)
34+
}
35+
36+
/// The file's type, from the mode's file-type bits.
37+
///
38+
/// Setting this property will mask the `newValue` with the file-type bit mask `S_IFMT`.
39+
@_alwaysEmitIntoClient
40+
public var type: FileType {
41+
get { FileType(rawValue: rawValue & _MODE_FILETYPE_MASK) }
42+
set { rawValue = (rawValue & ~_MODE_FILETYPE_MASK) | (newValue.rawValue & _MODE_FILETYPE_MASK) }
43+
}
44+
45+
/// The file's permissions, from the mode's permission bits.
46+
///
47+
/// Setting this property will mask the `newValue` with the permissions bit mask `ALLPERMS`.
48+
@_alwaysEmitIntoClient
49+
public var permissions: FilePermissions {
50+
get { FilePermissions(rawValue: rawValue & _MODE_PERMISSIONS_MASK) }
51+
set { rawValue = (rawValue & ~_MODE_PERMISSIONS_MASK) | (newValue.rawValue & _MODE_PERMISSIONS_MASK) }
52+
}
53+
}
54+
#endif

0 commit comments

Comments
 (0)