Skip to content

Commit 728d616

Browse files
committed
Stat implementation
1 parent 086219b commit 728d616

File tree

11 files changed

+1935
-9
lines changed

11 files changed

+1935
-9
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ let swiftSettings = swiftSettingsAvailability + swiftSettingsCI + [
8787

8888
let cSettings: [CSetting] = [
8989
.define("_CRT_SECURE_NO_WARNINGS", .when(platforms: [.windows])),
90+
.define("_GNU_SOURCE", .when(platforms: [.linux])),
9091
]
9192

9293
#if SYSTEM_ABI_STABLE
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
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+
// | compressed | UF_COMPRESSED | UF_COMPRESSED | N/A |
25+
// | tracked | UF_TRACKED | UF_TRACKED | N/A |
26+
// | hidden | UF_HIDDEN | UF_HIDDEN | N/A |
27+
// | restricted | SF_RESTRICTED | SF_RESTRICTED | N/A |
28+
// | systemNoUnlink | SF_NOUNLINK | SF_NOUNLINK | N/A |
29+
// | dataVault | UF_DATAVAULT | 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+
// @available(System X.Y.Z, *)
43+
extension CInterop {
44+
public typealias FileFlags = UInt32
45+
}
46+
47+
/// File-specific flags found in the `st_flags` property of a `stat` struct
48+
/// or used as input to `chflags()`.
49+
///
50+
/// - Note: Only available on Darwin, FreeBSD, and OpenBSD.
51+
@frozen
52+
// @available(System X.Y.Z, *)
53+
public struct FileFlags: OptionSet, Sendable, Hashable, Codable {
54+
55+
/// The raw C flags.
56+
@_alwaysEmitIntoClient
57+
public let rawValue: CInterop.FileFlags
58+
59+
/// Creates a strongly-typed `FileFlags` from the raw C value.
60+
@_alwaysEmitIntoClient
61+
public init(rawValue: CInterop.FileFlags) { self.rawValue = rawValue }
62+
63+
// MARK: Flags Available on Darwin, FreeBSD, and OpenBSD
64+
65+
/// Do not dump the file during backups.
66+
///
67+
/// The corresponding C constant is `UF_NODUMP`.
68+
/// - Note: This flag may be changed by the file owner or superuser.
69+
@_alwaysEmitIntoClient
70+
public static var noDump: FileFlags { FileFlags(rawValue: _UF_NODUMP) }
71+
72+
/// File may not be changed.
73+
///
74+
/// The corresponding C constant is `UF_IMMUTABLE`.
75+
/// - Note: This flag may be changed by the file owner or superuser.
76+
@_alwaysEmitIntoClient
77+
public static var userImmutable: FileFlags { FileFlags(rawValue: _UF_IMMUTABLE) }
78+
79+
/// Writes to the file may only append.
80+
///
81+
/// The corresponding C constant is `UF_APPEND`.
82+
/// - Note: This flag may be changed by the file owner or superuser.
83+
@_alwaysEmitIntoClient
84+
public static var userAppend: FileFlags { FileFlags(rawValue: _UF_APPEND) }
85+
86+
/// File has been archived.
87+
///
88+
/// The corresponding C constant is `SF_ARCHIVED`.
89+
/// - Note: This flag may only be changed by the superuser.
90+
@_alwaysEmitIntoClient
91+
public static var archived: FileFlags { FileFlags(rawValue: _SF_ARCHIVED) }
92+
93+
/// File may not be changed.
94+
///
95+
/// The corresponding C constant is `SF_IMMUTABLE`.
96+
/// - Note: This flag may only be changed by the superuser.
97+
@_alwaysEmitIntoClient
98+
public static var systemImmutable: FileFlags { FileFlags(rawValue: _SF_IMMUTABLE) }
99+
100+
/// Writes to the file may only append.
101+
///
102+
/// The corresponding C constant is `SF_APPEND`.
103+
/// - Note: This flag may only be changed by the superuser.
104+
@_alwaysEmitIntoClient
105+
public static var systemAppend: FileFlags { FileFlags(rawValue: _SF_APPEND) }
106+
107+
// MARK: Flags Available on Darwin and FreeBSD
108+
109+
#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD)
110+
/// Directory is opaque when viewed through a union mount.
111+
///
112+
/// The corresponding C constant is `UF_OPAQUE`.
113+
/// - Note: This flag may be changed by the file owner or superuser.
114+
@_alwaysEmitIntoClient
115+
public static var opaque: FileFlags { FileFlags(rawValue: _UF_OPAQUE) }
116+
117+
/// File is compressed at the file system level.
118+
///
119+
/// The corresponding C constant is `UF_COMPRESSED`.
120+
/// - Note: This flag is read-only. Attempting to change it will result in undefined behavior.
121+
@_alwaysEmitIntoClient
122+
public static var compressed: FileFlags { FileFlags(rawValue: _UF_COMPRESSED) }
123+
124+
/// File is tracked for the purpose of document IDs.
125+
///
126+
/// The corresponding C constant is `UF_TRACKED`.
127+
/// - Note: This flag may be changed by the file owner or superuser.
128+
@_alwaysEmitIntoClient
129+
public static var tracked: FileFlags { FileFlags(rawValue: _UF_TRACKED) }
130+
131+
/// File should not be displayed in a GUI.
132+
///
133+
/// The corresponding C constant is `UF_HIDDEN`.
134+
/// - Note: This flag may be changed by the file owner or superuser.
135+
@_alwaysEmitIntoClient
136+
public static var hidden: FileFlags { FileFlags(rawValue: _UF_HIDDEN) }
137+
138+
/// File requires an entitlement for writing.
139+
///
140+
/// The corresponding C constant is `SF_RESTRICTED`.
141+
/// - Note: This flag may only be changed by the superuser.
142+
@_alwaysEmitIntoClient
143+
public static var restricted: FileFlags { FileFlags(rawValue: _SF_RESTRICTED) }
144+
145+
/// File may not be removed or renamed.
146+
///
147+
/// The corresponding C constant is `SF_NOUNLINK`.
148+
/// - Note: This flag may only be changed by the superuser.
149+
@_alwaysEmitIntoClient
150+
public static var systemNoUnlink: FileFlags { FileFlags(rawValue: _SF_NOUNLINK) }
151+
#endif
152+
153+
// MARK: Flags Available on Darwin only
154+
155+
#if SYSTEM_PACKAGE_DARWIN
156+
/// File requires an entitlement for reading and writing.
157+
///
158+
/// The corresponding C constant is `UF_DATAVAULT`.
159+
/// - Note: This flag may be changed by the file owner or superuser.
160+
@_alwaysEmitIntoClient
161+
public static var dataVault: FileFlags { FileFlags(rawValue: _UF_DATAVAULT) }
162+
163+
/// File is a firmlink.
164+
///
165+
/// Firmlinks are used by macOS to create transparent links between
166+
/// the read-only system volume and writable data volume. For example,
167+
/// the `/Applications` folder on the system volume is a firmlink to
168+
/// the `/Applications` folder on the data volume, allowing the user
169+
/// to see both system- and user-installed applications in a single folder.
170+
///
171+
/// The corresponding C constant is `SF_FIRMLINK`.
172+
/// - Note: This flag may only be changed by the superuser.
173+
@_alwaysEmitIntoClient
174+
public static var firmlink: FileFlags { FileFlags(rawValue: _SF_FIRMLINK) }
175+
176+
/// File is a dataless placeholder (content is stored remotely).
177+
///
178+
/// The system will attempt to materialize the file when accessed according to
179+
/// the dataless file materialization policy of the accessing thread or process.
180+
/// See `getiopolicy_np(3)`.
181+
///
182+
/// The corresponding C constant is `SF_DATALESS`.
183+
/// - Note: This flag is read-only. Attempting to change it will result in undefined behavior.
184+
@_alwaysEmitIntoClient
185+
public static var dataless: FileFlags { FileFlags(rawValue: _SF_DATALESS) }
186+
#endif
187+
188+
// MARK: Flags Available on FreeBSD Only
189+
190+
#if os(FreeBSD)
191+
/// File may not be removed or renamed.
192+
///
193+
/// The corresponding C constant is `UF_NOUNLINK`.
194+
/// - Note: This flag may be changed by the file owner or superuser.
195+
@_alwaysEmitIntoClient
196+
public static var userNoUnlink: FileFlags { FileFlags(rawValue: _UF_NOUNLINK) }
197+
198+
/// File has the Windows offline attribute.
199+
///
200+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_OFFLINE` attribute,
201+
/// but otherwise provide no special handling when it's set.
202+
///
203+
/// The corresponding C constant is `UF_OFFLINE`.
204+
/// - Note: This flag may be changed by the file owner or superuser.
205+
@_alwaysEmitIntoClient
206+
public static var offline: FileFlags { FileFlags(rawValue: _UF_OFFLINE) }
207+
208+
/// File is read-only.
209+
///
210+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_READONLY` attribute.
211+
///
212+
/// The corresponding C constant is `UF_READONLY`.
213+
/// - Note: This flag may be changed by the file owner or superuser.
214+
@_alwaysEmitIntoClient
215+
public static var readOnly: FileFlags { FileFlags(rawValue: _UF_READONLY) }
216+
217+
/// File contains a Windows reparse point.
218+
///
219+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_REPARSE_POINT` attribute.
220+
///
221+
/// The corresponding C constant is `UF_REPARSE`.
222+
/// - Note: This flag may be changed by the file owner or superuser.
223+
@_alwaysEmitIntoClient
224+
public static var reparse: FileFlags { FileFlags(rawValue: _UF_REPARSE) }
225+
226+
/// File is sparse.
227+
///
228+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_SPARSE_FILE` attribute,
229+
/// or to indicate a sparse file.
230+
///
231+
/// The corresponding C constant is `UF_SPARSE`.
232+
/// - Note: This flag may be changed by the file owner or superuser.
233+
@_alwaysEmitIntoClient
234+
public static var sparse: FileFlags { FileFlags(rawValue: _UF_SPARSE) }
235+
236+
/// File has the Windows system attribute.
237+
///
238+
/// File systems may use this flag for compatibility with the Windows `FILE_ATTRIBUTE_SYSTEM` attribute,
239+
/// but otherwise provide no special handling when it's set.
240+
///
241+
/// The corresponding C constant is `UF_SYSTEM`.
242+
/// - Note: This flag may be changed by the file owner or superuser.
243+
@_alwaysEmitIntoClient
244+
public static var system: FileFlags { FileFlags(rawValue: _UF_SYSTEM) }
245+
246+
/// File is a snapshot.
247+
///
248+
/// The corresponding C constant is `SF_SNAPSHOT`.
249+
/// - Note: This flag may only be changed by the superuser.
250+
@_alwaysEmitIntoClient
251+
public static var snapshot: FileFlags { FileFlags(rawValue: _SF_SNAPSHOT) }
252+
#endif
253+
}
254+
#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 X.Y.Z, *)
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 `0o7777`.
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)