-
Notifications
You must be signed in to change notification settings - Fork 125
[Proposal] Stat for Swift System #257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
} | ||
``` | ||
|
||
These initializers use a typed `throws(Errno)` and require Swift 6.0 or later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's typically not recommended to use typed throws in public API (or ABI, which impacts Darwin). Are you sure this is the right choice always and forever?
/// The corresponding C constant is `S_IFSOCK`. | ||
public static var socket: FileType { get } | ||
|
||
#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any particular reasoning for using ifdef vs @available(OpenBSD, unavailable)
, etc., for the platforms where it isn't available? Might provide a nicer developer experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we're able to do that since the constant itself won't be available on those platforms, so the implementation will fail to build unless we ifdef the constant out. Maybe we could define the constant to be some bogus value on platforms where it doesn't exist, and then mark the public API unavailable? If I'm missing a common pattern for this please let me know and I'd be happy to look into it!
It would also help if there were a @available(Darwin, unavailable)
to avoid doing it for each platform I think.
/// Time of last access, given as a `UTCClock.Instant` | ||
/// | ||
/// The corresponding C property is `st_atim` (or `st_atimespec` on Darwin). | ||
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should probably list visionOS availability for completeness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thanks yeah I'll make sure to do that in the future. I'm actually planning to remove these particular availability annotations since they're accidentally left over from when I used Duration
here. I'll need to update it with the appropriate UTCClock
availability when that proposal is settled.
Combining `Stat` and `StatFS` (separate proposal) into a single type was considered but rejected because file and file system information serve different purposes and are typically needed in different contexts. Storing and/or initializing both `stat` and `statfs` structs unnecessarily reduces performance when one isn't needed. | ||
|
||
### Making `Stat` available on Windows | ||
It's possible to make `Stat` available on Windows and use either the non-native `_stat` functions from CRT or populate the information via a separate `GetFileInformation` call. However, many of the `stat` fields are not- or less-applicable on Windows and are treated as such by `_stat`. For instance, `st_uid` is always zero on Windows, `st_ino` has no meaning in FAT, HPFS, or NTFS file systems, and `st_mode` can only specify a regular file, directory, or character special, with the executable bit depending entirely on the file's path extension. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with the rationale about many of the fields being not applicable or less applicable on Windows. Windows clearly provides and meticulously documents the POSIX-like wrappers like _stat, _wstat, and so on, to make porting existing code easier, so why not use them? I don't think it's an either/or thing -- we could make Stat available on Windows and create Windows-specific types that give developers full access to platform-native file metadata.
I think whether third party developers want to use the POSIX-ish family or functions or the Win32 functions is a choice they should decide for themselves, not one Swift System should effectively make for them.
Letting the Stat type wrap the POSIX functions on Windows provides the best of both worlds if we also provide a Win32-level abstraction later.
The Win32 API surface is also pretty large, and I wonder if general Win32 abstractions would be better handled by apinotes that we distribute with the Swift for Windows installer to project those APIs into more idiomatic Swift, rather than wrapper APIs in a package like this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that Windows's documentation of _stat
et al. is complete, but it's not particularly intuitive. I think using _stat
for Windows would then put the onus on System for properly documenting and explaining all the (possibly unexpected) differences. I sympathize with giving third party developers the ability to choose, but I worry this would inherently make the Stat
type more confusing. It also clashes a bit with System's "no abstraction" philosophy.
We could always re-visit this in the future if there's a demonstrated desire for supporting the POSIX-like wrappers on Windows. I'm also happy to hear ideas on how we could make the documentation around that more clear.
Using apinotes for the vast array of Win32 APIs is definitely an interesting idea I'd like to learn more about. I wonder if some of the more basic ones like GetFileInformationByHandle
could still be useful to have in System, though.
This proposal introduces a Swift-native
Stat
type to the System library, providing comprehensive access to file metadata on Unix-like platforms through type-safe, platform-aware APIs that wrap the Cstat
types and system calls.Read full proposal...