Skip to content

Commit 62512aa

Browse files
committed
WIP: Ideas for stat.h interface
1 parent a74751c commit 62512aa

13 files changed

+1575
-4
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
swift-system.xcodeproj
66
xcuserdata/
77
.*.sw?
8-
.docc-build
8+
.docc-build
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
11+
12+
// FIXME: Document
13+
@frozen
14+
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
15+
public struct FileFlags: OptionSet, Hashable, Codable {
16+
/// The raw C file flags.
17+
@_alwaysEmitIntoClient
18+
public let rawValue: CInterop.FileFlags
19+
20+
/// Create a strongly-typed file flags from a raw C value.
21+
@_alwaysEmitIntoClient
22+
public init(rawValue: CInterop.FileFlags) { self.rawValue = rawValue }
23+
24+
@_alwaysEmitIntoClient
25+
private init(_ raw: CInterop.FileFlags) { self.init(rawValue: raw) }
26+
27+
/// Do not dump the file. Modifiable by file owner or super-user.
28+
///
29+
/// The corresponding C constant is `UF_NODUMP`
30+
@_alwaysEmitIntoClient
31+
public static var noDump: FileFlags { FileFlags(_UF_NODUMP) }
32+
33+
@_alwaysEmitIntoClient
34+
@available(*, unavailable, renamed: "noDump")
35+
public static var UF_NODUMP: FileFlags { noDump }
36+
37+
/// The file may not be changed. Modifiable by file owner or super-user.
38+
///
39+
/// The corresponding C constant is `UF_IMMUTABLE`
40+
@_alwaysEmitIntoClient
41+
public static var immutable: FileFlags { FileFlags(_UF_IMMUTABLE) }
42+
43+
@_alwaysEmitIntoClient
44+
@available(*, unavailable, renamed: "immutable")
45+
public static var UF_IMMUTABLE: FileFlags { immutable }
46+
47+
/// The file may only be appended to. Modifiable by file owner or super-user.
48+
///
49+
/// The corresponding C constant is `UF_APPEND`
50+
@_alwaysEmitIntoClient
51+
public static var appendOnly: FileFlags { FileFlags(_UF_APPEND) }
52+
53+
@_alwaysEmitIntoClient
54+
@available(*, unavailable, renamed: "appendOnly")
55+
public static var UF_APPEND: FileFlags { appendOnly }
56+
57+
/// The directory is opaque when viewed through a union stack. Modifiable by file owner or super-user.
58+
///
59+
/// The corresponding C constant is `UF_OPAQUE`
60+
@_alwaysEmitIntoClient
61+
public static var opaque: FileFlags { FileFlags(_UF_OPAQUE) }
62+
63+
@_alwaysEmitIntoClient
64+
@available(*, unavailable, renamed: "opaque")
65+
public static var UF_OPAQUE: FileFlags { opaque }
66+
67+
// #if os(FreeBSD)
68+
// /// The file may not be removed or renamed. Modifiable by file owner or super-user.
69+
// ///
70+
// /// The corresponding C constant is `UF_NOUNLINK`
71+
// @_alwaysEmitIntoClient
72+
// public static var noUnlink: FileFlags { FileFlags(_UF_NOUNLINK) }
73+
//
74+
// @_alwaysEmitIntoClient
75+
// @available(*, unavailable, renamed: "noUnlink")
76+
// public static var UF_NOUNLINK: FileFlags { noUnlink }
77+
// #endif
78+
79+
/// The file is compressed (some file-systems). Modifiable by file owner or super-user.
80+
///
81+
/// The corresponding C constant is `UF_COMPRESSED`
82+
@_alwaysEmitIntoClient
83+
public static var compressed: FileFlags { FileFlags(_UF_COMPRESSED) }
84+
85+
@_alwaysEmitIntoClient
86+
@available(*, unavailable, renamed: "compressed")
87+
public static var UF_COMPRESSED: FileFlags { compressed }
88+
89+
/// No notifications will be issued for deletes or renames. Modifiable by file owner or super-user.
90+
///
91+
/// The corresponding C constant is `UF_TRACKED`
92+
@_alwaysEmitIntoClient
93+
public static var tracked: FileFlags { FileFlags(_UF_TRACKED) }
94+
95+
@_alwaysEmitIntoClient
96+
@available(*, unavailable, renamed: "tracked")
97+
public static var UF_TRACKED: FileFlags { tracked }
98+
99+
/// The file requires entitlement required for reading and writing. Modifiable by file owner or super-user.
100+
///
101+
/// The corresponding C constant is `UF_DATAVAULT`
102+
@_alwaysEmitIntoClient
103+
public static var dataVault: FileFlags { FileFlags(_UF_DATAVAULT) }
104+
105+
@_alwaysEmitIntoClient
106+
@available(*, unavailable, renamed: "dataVault")
107+
public static var UF_DATAVAULT: FileFlags { dataVault }
108+
109+
/// The file or directory is not intended to be displayed to the user. Modifiable by file owner or super-user.
110+
///
111+
/// The corresponding C constant is `UF_HIDDEN`
112+
@_alwaysEmitIntoClient
113+
public static var hidden: FileFlags { FileFlags(_UF_HIDDEN) }
114+
115+
@_alwaysEmitIntoClient
116+
@available(*, unavailable, renamed: "hidden")
117+
public static var UF_HIDDEN: FileFlags { hidden }
118+
119+
/// The file has been archived. Only modifiable by the super-user.
120+
///
121+
/// The corresponding C constant is `SF_ARCHIVED`
122+
@_alwaysEmitIntoClient
123+
public static var superUserArchived: FileFlags { FileFlags(_SF_ARCHIVED) }
124+
125+
@_alwaysEmitIntoClient
126+
@available(*, unavailable, renamed: "superUserArchived")
127+
public static var SF_ARCHIVED: FileFlags { superUserArchived }
128+
129+
/// The file may not be changed. Only modifiable by the super-user.
130+
///
131+
/// The corresponding C constant is `SF_IMMUTABLE`
132+
@_alwaysEmitIntoClient
133+
public static var superUserImmutable: FileFlags { FileFlags(_SF_IMMUTABLE) }
134+
135+
@_alwaysEmitIntoClient
136+
@available(*, unavailable, renamed: "superUserImmutable")
137+
public static var SF_IMMUTABLE: FileFlags { superUserImmutable }
138+
139+
/// The file may only be appended to. Only modifiable by the super-user.
140+
///
141+
/// The corresponding C constant is `SF_APPEND`
142+
@_alwaysEmitIntoClient
143+
public static var superUserAppend: FileFlags { FileFlags(_SF_APPEND) }
144+
145+
@_alwaysEmitIntoClient
146+
@available(*, unavailable, renamed: "superUserAppend")
147+
public static var SF_APPEND: FileFlags { superUserAppend }
148+
149+
/// The file requires entitlement required for reading and writing. Only modifiable by the super-user.
150+
///
151+
/// The corresponding C constant is `SF_RESTRICTED`
152+
@_alwaysEmitIntoClient
153+
public static var superUserRestricted: FileFlags { FileFlags(_SF_RESTRICTED) }
154+
155+
@_alwaysEmitIntoClient
156+
@available(*, unavailable, renamed: "superUserRestricted")
157+
public static var SF_RESTRICTED: FileFlags { superUserRestricted }
158+
159+
/// The file may not be removed, renamed or mounted on. Only modifiable by the super-user.
160+
///
161+
/// The corresponding C constant is `SF_NOUNLINK`
162+
@_alwaysEmitIntoClient
163+
public static var superUserNoUnlink: FileFlags { FileFlags(_SF_NOUNLINK) }
164+
165+
@_alwaysEmitIntoClient
166+
@available(*, unavailable, renamed: "superUserNoUnlink")
167+
public static var SF_NOUNLINK: FileFlags { superUserNoUnlink }
168+
169+
// #if os(FreeBSD)
170+
// /// The file is a snapshot file. Only modifiable by the super-user.
171+
// ///
172+
// /// The corresponding C constant is `SF_SNAPSHOT`
173+
// @_alwaysEmitIntoClient
174+
// public static var superUserSnapshot: FileFlags { FileFlags(_SF_SNAPSHOT) }
175+
//
176+
// @_alwaysEmitIntoClient
177+
// @available(*, unavailable, renamed: "superUserSnapshot")
178+
// public static var SF_SNAPSHOT: FileFlags { superUserSnapshot }
179+
// #endif
180+
181+
/// The file is a firmlink. Only modifiable by the super-user.
182+
///
183+
/// The corresponding C constant is `SF_FIRMLINK`
184+
@_alwaysEmitIntoClient
185+
public static var superUserFirmlink: FileFlags { FileFlags(_SF_FIRMLINK) }
186+
187+
@_alwaysEmitIntoClient
188+
@available(*, unavailable, renamed: "superUserFirmlink")
189+
public static var SF_FIRMLINK: FileFlags { superUserFirmlink }
190+
191+
/// The file is a dataless placeholder. The system will attempt to materialize it when accessed according to the dataless file materialization policy of the accessing thread or process. Cannot be modified in user-space.
192+
///
193+
/// The corresponding C constant is `SF_DATALESS`
194+
@_alwaysEmitIntoClient
195+
public static var kernelDataless: FileFlags { FileFlags(_SF_DATALESS) }
196+
197+
@_alwaysEmitIntoClient
198+
@available(*, unavailable, renamed: "kernelDataless")
199+
public static var SF_DATALESS: FileFlags { kernelDataless }
200+
}
201+
202+
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
203+
extension FileFlags
204+
: CustomStringConvertible, CustomDebugStringConvertible
205+
{
206+
/// A textual representation of the file permissions.
207+
@inline(never)
208+
public var description: String {
209+
let descriptions: [(Element, StaticString)] = [
210+
(.noDump, ".noDump"),
211+
(.immutable, ".immutable"),
212+
(.appendOnly, ".appendOnly"),
213+
(.opaque, ".opaque"),
214+
(.compressed, ".compressed"),
215+
(.tracked, ".tracked"),
216+
(.dataVault, ".dataVault"),
217+
(.hidden, ".hidden"),
218+
(.superUserArchived, ".superUserArchived"),
219+
(.superUserImmutable, ".superUserImmutable"),
220+
(.superUserAppend, ".superUserAppend"),
221+
(.superUserRestricted, ".superUserRestricted"),
222+
(.superUserNoUnlink, ".superUserNoUnlink"),
223+
(.superUserFirmlink, ".superUserFirmlink"),
224+
(.kernelDataless, ".kernelDataless"),
225+
]
226+
227+
return _buildDescription(descriptions)
228+
}
229+
230+
/// A textual representation of the file permissions, suitable for debugging.
231+
public var debugDescription: String { self.description }
232+
}
233+
234+
#endif
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
11+
12+
// FIXME: should the subtypes of Mode mask their rawValues to only allow their bits to be changed?
13+
14+
/// The superset of access permissions and type for a file.
15+
///
16+
/// The following example creates an instance of the `FileMode` structure
17+
/// from a raw octal literal and reads the file type from it:
18+
///
19+
/// let mode = FileMode(rawValue: 0o140000)
20+
/// mode.type == .socket // true
21+
@frozen
22+
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
23+
public struct FileMode: RawRepresentable {
24+
/// The raw C file mode.
25+
@_alwaysEmitIntoClient
26+
public var rawValue: CInterop.Mode
27+
28+
/// Create a strongly-typed file mode from a raw C value.
29+
@_alwaysEmitIntoClient
30+
public init(rawValue: CInterop.Mode) { self.rawValue = rawValue }
31+
32+
/// Subset of mode for accessing and modifying file permissions.
33+
@_alwaysEmitIntoClient
34+
public var permissions: FilePermissions {
35+
get { FilePermissions(rawValue: rawValue & _MODE_PERMISSIONS) }
36+
set { rawValue = (rawValue & ~_MODE_PERMISSIONS) | (newValue.rawValue & _MODE_PERMISSIONS ) }
37+
}
38+
39+
/// Subset of mode for accessing and modifying file type.
40+
@_alwaysEmitIntoClient
41+
public var type: FileType {
42+
get { FileType(rawValue: rawValue & _MODE_TYPE) }
43+
set { rawValue = (rawValue & ~_MODE_TYPE) | (newValue.rawValue & _MODE_TYPE ) }
44+
}
45+
}
46+
47+
#endif
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
11+
import Darwin
12+
13+
// FIXME: Document
14+
@frozen
15+
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
16+
public struct FileStatus: RawRepresentable {
17+
/// The raw C file status.
18+
@_alwaysEmitIntoClient
19+
public let rawValue: CInterop.Stat
20+
21+
/// Create a strongly-typed file status from a raw C value.
22+
@_alwaysEmitIntoClient
23+
public init(rawValue: CInterop.Stat) { self.rawValue = rawValue }
24+
25+
// FIXME: replace with swift type DeviceID that splits out major/minor
26+
/// ID of device containing file.
27+
@_alwaysEmitIntoClient
28+
public var deviceID: CInterop.DeviceID { rawValue.st_dev }
29+
30+
/// Mode of file.
31+
@_alwaysEmitIntoClient
32+
public var mode: FileMode { FileMode(rawValue: rawValue.st_mode) }
33+
34+
/// Number of hard links.
35+
@_alwaysEmitIntoClient
36+
public var hardLinkCount: CInterop.NumberOfLinks { rawValue.st_nlink }
37+
38+
/// File serial number.
39+
@_alwaysEmitIntoClient
40+
public var inodeNumber: CInterop.INodeNumber { rawValue.st_ino }
41+
42+
/// User ID of the file.
43+
@_alwaysEmitIntoClient
44+
public var userID: CInterop.UserID { rawValue.st_uid }
45+
46+
/// Group ID of the file.
47+
@_alwaysEmitIntoClient
48+
public var groupID: CInterop.GroupID { rawValue.st_gid }
49+
50+
/// Device ID.
51+
@_alwaysEmitIntoClient
52+
public var rDeviceID: CInterop.DeviceID { rawValue.st_rdev }
53+
54+
/// Time of last access.
55+
@_alwaysEmitIntoClient
56+
public var accessTime: TimeSpecification { TimeSpecification(rawValue: rawValue.st_atimespec) }
57+
58+
/// Time of last data modification.
59+
@_alwaysEmitIntoClient
60+
public var modifyTime: TimeSpecification { TimeSpecification(rawValue: rawValue.st_mtimespec) }
61+
62+
/// Time of last status change.
63+
@_alwaysEmitIntoClient
64+
public var statusChangeTime: TimeSpecification { TimeSpecification(rawValue: rawValue.st_ctimespec) }
65+
66+
/// Time of file creation.
67+
@_alwaysEmitIntoClient
68+
public var creationTime: TimeSpecification { TimeSpecification(rawValue: rawValue.st_birthtimespec) }
69+
70+
/// File size, in bytes.
71+
@_alwaysEmitIntoClient
72+
public var fileSize: CInterop.Offset { rawValue.st_size }
73+
74+
/// Blocks allocated for file.
75+
@_alwaysEmitIntoClient
76+
public var blockCount: CInterop.BlockCount { rawValue.st_blocks }
77+
78+
/// Optimal block size for I/O.
79+
@_alwaysEmitIntoClient
80+
public var blockSize: CInterop.BlockSize { rawValue.st_blksize }
81+
82+
/// User defined flags for file.
83+
@_alwaysEmitIntoClient
84+
public var fileFlags: FileFlags { FileFlags(rawValue: rawValue.st_flags) }
85+
86+
/// File generation number.
87+
@_alwaysEmitIntoClient
88+
public var generationID: CInterop.GenerationID { rawValue.st_gen }
89+
}
90+
91+
#endif

0 commit comments

Comments
 (0)