* std.option allows overriding the debug Io instance
* if the default is used, start code initializes environ and argv0
also fix some places that needed recancel(), thanks mlugg!
See #30562
This is needed unfortunately for OpenBSD and Haiku for process
executable path.
I made it so that you can omit the options usually, but you get a
compile error if you omit the options on those targets.
* policy is to always handle EINTR from all syscalls
* assert the result of realpath
* don't ignore errors from realpath
* hard-code path separators for code simplicity
Since we know the read will fail for directories, we can take advantage
of Windows being able to fail with IsDir during open to avoid needing to
wait until the read to find out about the directory-ness of the file.
It's better to avoid references to this global variable, but, in the
cases where it's needed, such as in std.debug.print and collecting stack
traces, better to share the same instance.
Stephen Gregoratto (original author of the fallback) says:
I read through both libcs again to compare:
Musl:
- `stat` path. Check error.
- If path is a symlink, return `OPNOTSUPP`.
- `openat` path as `O_PATH|O_NOFOLLOW|O_CLOEXEC`. Return `OPNOTSUPP` if we got `ELOOP`.
- Build procfs filename.
- `stat` procfs file.
- If procfs file is a symlink, return `OPNOTSUPP`.
- close path fd.
Glibc:
- open path as `O_PATH|O_NOFOLLOW|O_CLOEXEC`.
- fstatat path fd.
- If path is a symlink, return `OPNOTSUPP`.
- Build procfs filename.
- chmod procfs filename. Return `OPNOTSUPP` if we got `ENOENT`.
- close path fd.
I prefer glibc since you open the path first, which avoids a possible
TOCTOU race.
The only known situation in which this occurs is when using musl with
the undocumented extension PTHREAD_CANCEL_MASKED, causing the next
syscall to return ECANCELED.
However zig std lib does not use this mechanism, even when targeting
musl libc because it would require each async task to be on a fresh
pthread.
For the same reason, if third party code were to cause ECANCELED to be
returned from any of these syscalls, it would cause subsequent tasks to
be incorrectly canceled since they cannot be rearmed.
Thus, this Io implementation cannot handle this error code correctly,
expecting never to receive it.