-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
rework the POSIX API layer in the standard library #2380
Comments
How far should the "posix" library go? Only include things specified by posix? What about APIs that almost all posix platforms provide? I imagine the file structure will be:
Where |
It can have everything that would be convenient to abstract across operating systems at the posix layer. It can go beyond posix specifications. For example there can be a kqueue function. The goal is not to be compliant in any sense; more to provide an API at the same level of abstraction.
They're in 👍
That looks right. The std/posix/linux.zig etc files might not be necessary, depending on how much code there ends up being in std/posix.zig. |
I think using "posix" to mean anything other than what is actually defined as API/ABI in the posix standard itself is dangerous: what happens if POSIX gets updated and gains functions with the same name as whatever we define? Perhaps we should name our module something else? And have a "posix" module only contain what is actually in posix? That way if your program only used the posix library, then you'd know that your zig program is portable to any OS that claims POSIX compliance (which of course is the whole point of POSIX). |
Hijacking the word "posix" does feel weird. Why not have cross-OS abstractions just live in |
If My main question is what would differentiate |
We do have those already, and those are the preferred cross-platform abstractions for general use. Most of the implementations of these use the posix API layer for non-windows. This abstraction layer exists today. If it's not called An example "posix" abstraction layer function is to
If POSIX got a sendmmsg then it would work perfectly. What other example are you thinking of that is problematic? |
There have been plenty of times in the past where things have gotten mixed up as they make their way into posix. |
Ah, so this new "posix" is more of an abstraction for the sake of stdlib internals? (But possibly also useful outside of that?)
Right — sorry, I didn't quite get that before. Like this? I think it makes more sense to me with that explanation. |
Yes, precisely. |
Could it go in a |
Alternate name suggestions are welcome. I think |
My suggestion:
|
Alternate name suggestion: |
@jayschwa I like your idea - I think it does solve some problems. There are 2 things that make me hesitate:
|
elevate |
I believe it would be better to group abstractions by functionality than by implementation. I might be straying too far from the original topic with the following hypothetical, but it illustrates what I mean. Right now, the idea of a "file" in Zig is OS-specific, but consider that other modules might want to satisfy Zig's (hypothetical) interface for files (e.g. reading, writing, seeking) or filesystems (e.g. listing, opening, renaming, walking). Examples of implementing modules could be const os_fs = try std.os.file_system() // some kind of `std.fs.FileSystem` interface
const zip_file = try os_fs.open("foo.zip") // some kind of `std.fs.File` interface
const zip_fs = try zip.from_file(zip_file).file_system()
const zip_walk = zip_fs.walk()
while (zip_walk.next()) |path| {} Note that my original suggestion (
Agreed that it would be difficult to know from name alone which is the high versus low-level one. Personally, if I needed a foo and I saw a |
I think @jayschwa's use case outlined above is an important one, which I would like to continue discussing. However for this particular issue, there is a pressing need to do this re-org as I've outlined originally. This issue brings us closer to being able to solve Jay's use case even if it does not bring us all the way there, so I'm going to do it and then we can re-evaluate (1) naming and (2) where to go next. And then finally remember we have the standard library audit (#1629) before 1.0.0 for yet another re-evaluation. |
Currently, we have these OS-specific APIs:
std.os.posix is defined like this:
So what we have is an identifier
posix
that is mapped directly to the OS-specific API for all platforms except Windows. This is problematic for several reasons:std.os.posixFoo
pattern, which is a code smell, because all the functions are all prefixed withposix
but cannot be in theposix
namespace.iov_len
is greater than some kernel-defined limit, it has to be broken into multiple syscalls. Or when the number of bytes to thewrite
syscall is greater than some number, it has to be broken into multiple syscalls.This led to 4a8c992 in which, for example,
std.os.linux.fork
surprisingly does not cause a fork syscall. Further, with the WASI ABI, it's clear that there is a separate "core" API layer as well as a "POSIX" API layer.I propose to make the following changes:
std.os.linux.fork
, that is going to do the fork syscall when you observe the program with strace, guaranteed.fork
might callclone
on Linux, etc.std.os.posixFoo
will be moved tostd.os.posix.foo
. In Zig-flavored POSIX, errno is not exposed; instead actual zig error unions and error sets are used. When not linking libc on Linux there will never be an errno variable, because the syscall return code contains the error code in it. However for OS-specific APIs, where that OS requires the use of libc, errno may be exposed, for example asstd.os.darwin.errno()
.The text was updated successfully, but these errors were encountered: