-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
The os namespace (to be renamed posix) is tackling the problem of providing a cross-platform abstraction over the operating system facilities from a, in my opinion, wrong angle. In this essay I will briefly explain why.
The aim here is having a single level of abstraction that works well enough both for direct consumers (users of std.os namespace) or indirect consumers (eg. using std.fs abstractions built on std.os) without leaking too many details about the underlying implementation. The current approach tries to clump everything under the posix name, a name that carries a heavy baggage of do's and dont's that other platforms (mainly Windows) may not agree with.
A few examples:
renamedoesn't follow the posix semantics on Windows, unless you have a very recent Windows 10 version andFILE_RENAME_FLAG_POSIX_SEMANTICSis used.openaccepts a well-defined set of options that's not even shared across all the posix-compatible and for Windows this means we're pinky-swearing to faithfully translate all of them into something equivalent. What if there's no direct equivalent? If you promise posix compatibility I'd expect something akin tomingw.- What we're interested in is getting a handle on a given file, with a given set of flags.
statdoesn't exist on Windows,GetFileAttributesExor equivalents are used and the resulting infos are chopped into a posixstatstructure. It's a clear case of square peg in a round hole as many fields are unix-specific.- What we're interested in is getting a basic set of infos about the file, platform-specific extra stuff may be retrieved/modified with a companion function.
preadv/pwritevare not available on Windows and, at the moment at least, you get a nice compile error trying to use them.- What we're interested in is a
{write,read}Manyfunction, implemented usingp{write,read}vorReadFileScatter/WriteFileGather. iovecis a posix thing, I just want to write/read a[][]u8!
- What we're interested in is a
copy_file_rangeis a Linux-only syscall with a fallback onpwrite/preadthat in turn falls back onReadFile/WriteFileon Windows.- IMO this doesn't even belong to
osas it can be safely implemented somewhere infs, callingcopy_file_rangeor other platform-specific APIs as needed. - It's not portable! It's not part of the posix standard!
copy_file_rangeis all about efficiency as it's done at the FS level, if the fallback path is triggered you get a disappointing read/write pair (not even a loop!)
- IMO this doesn't even belong to
The point is that we should aim at breaking free from the posix rules and write our own, a full-blown posix compatibility layer is not something that belongs to the stdlib. I see Rust took this very same approach (I'm looking at the filsystem-related part), their API surface is small and comprises all the common bits required by the users (external ones and ones working on the stdlib). A small note lets the user know what platform-specific method is used, but that's it.
The gist of this proposal is:
- No more posix compatibility layer
osbecomes the home of all the cross-platform native interactions with the OS. No fallbacks, no posix names, no posix guarantees.- No fallbacks really means no half-assed fallbacks, if something can be implemented across all the different platforms with a consistent set of characteristics it belongs to
os, otherwise down the platform-specific namespace it goes.- ✔️
writeManyimplemented withWriteFileGatherandpwritev - ❌
copy_file_rangecannot be implemented as zero-copy on Windows! (On other posix-compatible systemssendfilemay be used, but the gains are really small unless you're copying a lot of data (I'm using it to copy whole files in std: Make file copy ops use zero-copy mechanisms #6516))
- ✔️
- No fallbacks really means no half-assed fallbacks, if something can be implemented across all the different platforms with a consistent set of characteristics it belongs to
Thanks for watching.