-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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:
rename
doesn't follow the posix semantics on Windows, unless you have a very recent Windows 10 version andFILE_RENAME_FLAG_POSIX_SEMANTICS
is used.open
accepts 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.
stat
doesn't exist on Windows,GetFileAttributesEx
or equivalents are used and the resulting infos are chopped into a posixstat
structure. 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
/pwritev
are 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}Many
function, implemented usingp{write,read}v
orReadFileScatter
/WriteFileGather
. iovec
is a posix thing, I just want to write/read a[][]u8
!
- What we're interested in is a
copy_file_range
is a Linux-only syscall with a fallback onpwrite
/pread
that in turn falls back onReadFile
/WriteFile
on Windows.- IMO this doesn't even belong to
os
as it can be safely implemented somewhere infs
, callingcopy_file_range
or other platform-specific APIs as needed. - It's not portable! It's not part of the posix standard!
copy_file_range
is 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
os
becomes 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.- ✔️
writeMany
implemented withWriteFileGather
andpwritev
- ❌
copy_file_range
cannot be implemented as zero-copy on Windows! (On other posix-compatible systemssendfile
may 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.