News for hackers. Stuff that matters.

4lDO2

Generally this aligns with what the Redox kernel is currently transitioning into, with a few limitations in order to retain compatibility for the (quite larger number) of applications we "need" to support.

> My idea of operating system design is you do pass capabilities; actually, a message can only pass capabilities and byte sequences, and all I/O must use that interface.

File descriptors and capabilities are very similar, and Redox already uses file descriptors, which are handled by scheme daemons, for most interfaces in general. I'm working on a _virtual memory-based capability_ RFC, on top of which the POSIX file table can be implemented in redox-rt (userspace) without forcing (some) POSIX semantics onto capabilities.

> Actually, my operating system design does not have file paths.

We're eventually going to switch fully to the openat* family of path calls, which would generalize the open syscall into a scheme call that sends a capability reference (dirfd), a path, and returns a capability.

> However, for seeking it will require a message containing a command to request to seek the file, ...

But that the cursor to be stored either by the client (requiring extensive messaging for each non-absolute IO call), by the server (requiring unnecessary state since almost all positioned IO nowadays is random-access), or currently, in the kernel. I'd like this state to be stored in userspace, as the article mentions, but this will first require assessing whether it would be feasible to break compatibility for this, or at least "performant compatibility".

> the kernel is not POSIX, but a compatibility layer (for at least much of POSIX, but maybe not all of it necessarily) can be made in user space if it is desired.

This is exactly what Redox is transitioning to: a kernel that's not necessarily Unix-like, with the bulk of POSIX logic implemented in userspace (redox-rt).

Yes, and yes.
File descriptors and file descriptions are not the same thing. Descriptors are references to descriptions, along with some metadata, and multiple descriptors can point to the same description.
Rust does however implement the IO traits for `&File` as well (shared), and IIRC also implements `try_clone` which is the dup equivalent.
The rationale was discussed in-depth earlier on LWN (https://lwn.net/Articles/982186/).

Signals are useful as a software analogue to hardware interrupts, even though they are probably too low-level for most application use cases. They are for example used by the Golang runtime to preempt threads AFAIU, which wouldn't otherwise be possible non-cooperatively. Intel even included an ISA extension called user-IPIs, which is similar to signals.

I'm aware of this example, this was discussed earlier on HN [1]. I think it would be reasonable to (try to) enforce O_APPEND in such scenarios, in which case libc might internally open a pipe (configured to passively or actively be flushed to the underlying file, non-concurrently). A pipe would also be more reliable (and secure, though programs in shell pipelines are usually trusted), since it's no longer possible for isolated programs to change the global cursor, which could overwrite other processes' written data.

[1] https://news.ycombinator.com/item?id=38009458

Also, I feel like you are misquoting me, by not including the whole sentence (judging from the subcomments). I implied shared fds with shared cursors are probably a rare use cases, not shared fds in general (as you explained later on). Shared fds, and especially the ability to send fds, are obviously very fundamental for Unix-like systems, and for moving towards capability-oriented security.

Pipes lack a file cursor, but they still need to store the fcntl file description flags, so yes. This is emulated by the Redox kernel for old schemes, by inserting fcntl calls between the legacy read/write calls that don't allow passing the offset and flags. However, I'd argue that the fcntl flags are even more client-oriented than the cursor, say, O_NONBLOCK. Should it really be possible for isolated processes to set each others' nonblock flag (unless using preadv2/pwritev2 which is non-POSIX)?