The following functions were replaced with their *at variants or
similar:
- lstat -> lstat -> fstatat
- stat -> stat -> fstatat
- fstat -> fstatat
- fchmod -> fchmodat
- fchown -> fchownat
- lchown -> fchownat
- mkfifo -> mkfifoat
- open -> openat
- renameat -> renameat2
- rmdir -> unlinkat
- unlink -> unlinkat
- symlink-> symlinkat
The `open_flags` logic for fstatat was redundant, as this is already
handled (and better so) in `openat2`.
Additionally, the fstatat test succeeds in os-test, and no longer
returns EINVAL. This is because `O_SYMLINK` is no longer
unconditionally passed like it was before. This is a problem because
redoxfs returns EINVAL if a node isn't a symlink but set `O_SYMLINK`.
Additionally, this adds the `SYMLOOP_MAX` constant in `limits.h` to
replace the `MAX_LEVEL` magic number used during symlink resolution.
`fstat` was kept because it is more difficult than the others to do a
drop-in replacement in terms of `fstatat` for since a naive approach
would cause mutual recursion.
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.