Skip to content

Eliminate the POSIX API layer #6600

@LemonBoy

Description

@LemonBoy

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 and FILE_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 to mingw.
    • 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 posix stat 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 using p{write,read}v or ReadFileScatter/WriteFileGather.
    • iovec is a posix thing, I just want to write/read a [][]u8!
  • copy_file_range is a Linux-only syscall with a fallback on pwrite/pread that in turn falls back on ReadFile/WriteFile on Windows.
    • IMO this doesn't even belong to os as it can be safely implemented somewhere in fs, calling copy_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!)

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 with WriteFileGather and pwritev
      • copy_file_range cannot be implemented as zero-copy on Windows! (On other posix-compatible systems sendfile 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))

Thanks for watching.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingImplementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.standard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions