Inside of `openat2`, we are assuming that if we are passed
`AT_SYMLINK_NOFOLLOW` that we are also passed a symlink. This is simply
not the case, as POSIX defines the flag to only have a noticable effect
if the resolved path is a symlink. Therefore, we cannot assume that we
have a symlink if we see `AT_SYMLINK_NOFOLLOW`. The previous behavior
caused an `EINVAL` in redoxfs because we do a consistency check to
error out if we are passed `O_SYMLINK` (which was added because
`AT_SYMLINK_NOFOLLOW` was observed) and aren't a symlink.
Hmm, maybe a special errno like `ENOTLNK` should be deployed for this? It's
specific enough that it could possibly be added to a future POSIX.
I noticed that the Linux and Redox PALs both do very similar things for
a given FS function and its *at variant. For example, `mkdir()` is just
a call to `mkdirat()`. POSIX requires these to be equivalent.
Additionally, we use AT_EMPTY_PATH in some places but note that this is
not POSIX and is instead an extension that Linux (and Redox) implement.
That doesn't really matter though, since this is an implementation
detail. Implementations can choose to implement these functions anyway
and ignore the default impl. Such a case is `fstat`, because the current
Redox impl of `fstatat` relies on `fstat`, and this would cause infinite
recursion.
Future work:
POSIX says that `fcntl(fd, F_DUPFD, 0);` shall be equivalent to
`dup(fd);`. `dup2` might have cases where it can be implemented using
`dup3`. `dup` seemingly cannot be implemented in terms of `dup2`, so the
`fcntl` default implementation is sufficient. `pipe(fds)` is equivalent to
`pipe2(fds, 0);`.
Additionally, we were using the `access` syscall for x86_64 for our
linux PAL. I looked at the linux source and found that using the
`access`
syscall is equivalent to using `faccessat` as we do now: https://elixir.bootlin.com/linux/v6.17.5/source/fs/open.c#L550
Also, some of the `fcntl.h` functions were accidentally implemented and exported from `unistd.h`. They are supposed to be implemented in `fcntl.h` and exported to `unistd.h`. This is now the behavior.
`linkat(2)` doesn't have `AT_EMPTY_PATH` as a valid flag in this
implementation because it isn't POSIX. We have it (and have
support for it), but it is more effort to add it. If we need it at some
point, it can be added in about 3 lines.
`openat(2)` previously wasn't exposed, and William was not aware of
`Sys::openat`'s existence. We use it under the hood for `mkfifoat(2)`
and friends, so expose it as a libc API. This helps to pass more os-test tests.
Lastly, the 3 implemented syscalls here help pass some os-test tests.
Adds the implementation for the `alarm()` function and its underlying
`alarm_timespec` helper. This involves managing a process-global POSIX timer
to deliver SIGALRM signals.
We recently updated the kernel to give the "version" info in the
uname scheme. Now, we also put this info in the `utsname` struct for the
`uname` function.