Implement support for POSIX thread cancellations

This change makes some miracle modifications to the System Five system
call support, which lets us have safe, correct, and atomic handling of
thread cancellations. It all turned out to be cheaper than anticipated
because it wasn't necessary to modify the system call veneers. We were
able to encode the cancellability of each system call into the magnums
found in libc/sysv/syscalls.sh. Since cancellations are so waq, we are
also supporting a lovely Musl Libc mask feature for raising ECANCELED.
This commit is contained in:
Justine Tunney 2022-11-04 01:04:43 -07:00
parent 37d40e087f
commit 2278327eba
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
145 changed files with 715 additions and 265 deletions

View file

@ -61,7 +61,7 @@
SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10 win10:31336
MAKEFLAGS += -j --no-builtin-rules
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
.DELETE_ON_ERROR:

View file

@ -204,6 +204,7 @@ textwindows int __sig_raise(int sig, int si_code) {
if (1 <= sig && sig <= 64) {
if (!__sig_is_masked(sig)) {
++__sig_count;
// TODO(jart): ucontext_t support
__sig_handle(false, sig, si_code, 0);
return 0;
} else {

View file

@ -34,7 +34,7 @@ textwindows int sys_clock_nanosleep_nt(int clock, int flags,
for (;;) {
if (sys_clock_gettime_nt(clock, &now)) return -1;
if (_timespec_gte(now, abs)) return 0;
if (_check_interrupts(false, g_fds.p)) return eintr();
if (_check_interrupts(false, g_fds.p)) return -1;
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
_timespec_tomillis(_timespec_sub(abs, now))),
false);
@ -47,7 +47,7 @@ textwindows int sys_clock_nanosleep_nt(int clock, int flags,
if (_timespec_gte(now, abs)) return 0;
if (_check_interrupts(false, g_fds.p)) {
if (rem) *rem = _timespec_sub(abs, now);
return eintr();
return -1;
}
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
_timespec_tomillis(_timespec_sub(abs, now))),

View file

@ -80,6 +80,7 @@
* @raise EINVAL if `flags` has an unrecognized value
* @raise EINVAL if `req->tv_nsec [0,1000000000)`
* @raise ENOSYS on bare metal
* @cancellationpoint
* @returnserrno
* @norestart
*/

View file

@ -26,7 +26,7 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
int sys_fcntl(int fd, int cmd, uintptr_t arg) {
int sys_fcntl(int fd, int cmd, uintptr_t arg, int impl(int, int, ...)) {
int e, rc;
bool islock;
if ((islock = cmd == F_GETLK || //
@ -40,12 +40,12 @@ int sys_fcntl(int fd, int cmd, uintptr_t arg) {
cosmo2flock(arg);
}
e = errno;
rc = __sys_fcntl(fd, cmd, arg);
rc = impl(fd, cmd, arg);
if (islock) {
flock2cosmo(arg);
} else if (rc == -1 && cmd == F_DUPFD_CLOEXEC && errno == EINVAL) {
errno = e;
rc = __fixupnewfd(__sys_fcntl(fd, F_DUPFD, arg), O_CLOEXEC);
rc = __fixupnewfd(impl(fd, F_DUPFD, arg), O_CLOEXEC);
}
return rc;
}

View file

@ -94,6 +94,7 @@
* @raise EDEADLK if `cmd` was `F_SETLKW` and waiting would deadlock
* @raise EMFILE if `cmd` is `F_DUPFD` or `F_DUPFD_CLOEXEC` and
* `RLIMIT_NOFILE` would be exceeded
* @cancellationpoint when `cmd` is `F_SETLKW`
* @asyncsignalsafe
* @restartable
*/
@ -111,7 +112,11 @@ int fcntl(int fd, int cmd, ...) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
rc = _weaken(__zipos_fcntl)(fd, cmd, arg);
} else if (!IsWindows()) {
rc = sys_fcntl(fd, cmd, arg);
if (cmd == F_SETLKW) {
rc = sys_fcntl(fd, cmd, arg, __sys_fcntl_cp);
} else {
rc = sys_fcntl(fd, cmd, arg, __sys_fcntl);
}
} else {
rc = sys_fcntl_nt(fd, cmd, arg);
}

View file

@ -30,6 +30,7 @@
* @return 0 on success, or -1 w/ errno
* @see sync(), fsync(), sync_file_range()
* @see __nosync to secretly disable
* @cancellationpoint
* @asyncsignalsafe
*/
int fdatasync(int fd) {

View file

@ -17,10 +17,10 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
/**
* Acquires lock on file.
@ -30,6 +30,7 @@
* @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive,
* non-blocking, and unlocking
* @return 0 on success, or -1 w/ errno
* @cancellationpoint
* @restartable
*/
int flock(int fd, int op) {

View file

@ -18,16 +18,17 @@
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/statfs-meta.internal.h"
#include "libc/calls/struct/statfs.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/errfuns.h"
/**
* Returns information about filesystem.
* @return 0 on success, or -1 w/ errno
* @cancellationpoint
*/
int fstatfs(int fd, struct statfs *sf) {
int rc;

View file

@ -30,6 +30,7 @@
* @return 0 on success, or -1 w/ errno
* @see fdatasync(), sync_file_range()
* @see __nosync to secretly disable
* @cancellationpoint
* @asyncsignalsafe
*/
int fsync(int fd) {

View file

@ -56,7 +56,7 @@
* @raise EINVAL if `fd` is a non-file, e.g. pipe, socket
* @raise EINVAL if `fd` wasn't opened in a writeable mode
* @raise ENOSYS on bare metal
* @see truncate()
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
*/

View file

@ -43,7 +43,7 @@ forceinline size_t _clampio(size_t size) {
}
int sys_close_nt(struct Fd *, int) hidden;
bool _check_interrupts(bool, struct Fd *) hidden;
int _check_interrupts(bool, struct Fd *) hidden;
int sys_openat_metal(int, const char *, int, unsigned);
COSMOPOLITAN_C_END_

View file

@ -18,24 +18,33 @@
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/fd.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/lockcmpxchgp.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
textwindows bool _check_interrupts(bool restartable, struct Fd *fd) {
bool res;
textwindows int _check_interrupts(bool restartable, struct Fd *fd) {
int rc;
if (_weaken(pthread_testcancel_np) &&
(rc = _weaken(pthread_testcancel_np)())) {
errno = rc;
return -1;
}
if (_weaken(_check_sigalrm)) _weaken(_check_sigalrm)();
if (!__tls_enabled || !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (_weaken(_check_sigchld)) _weaken(_check_sigchld)();
if (fd && _weaken(_check_sigwinch)) _weaken(_check_sigwinch)(fd);
}
res = _weaken(__sig_check) && _weaken(__sig_check)(restartable);
return res;
if (_weaken(__sig_check) && _weaken(__sig_check)(restartable)) return eintr();
return 0;
}

View file

@ -32,6 +32,7 @@
* @raise EFAULT if `req` is NULL or `req` / `rem` is a bad pointer
* @raise ENOSYS on bare metal
* @see clock_nanosleep()
* @cancellationpoint
* @norestart
*/
int nanosleep(const struct timespec *req, struct timespec *rem) {

View file

@ -21,6 +21,8 @@
#include "libc/nt/struct/context.h"
#include "libc/str/str.h"
// TODO(jart): uc_sigmask support
privileged void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
if (!cr) return;
ctx->uc_mcontext.eflags = cr->EFlags;

View file

@ -29,6 +29,7 @@
* @param file specifies filesystem path to open
* @return file descriptor, or -1 w/ errno
* @see openat() for further documentation
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @threadsafe

View file

@ -141,6 +141,7 @@
* @raise ELOOP if `flags` had `O_NOFOLLOW` and `file` is a symbolic link
* @raise ELOOP if a loop was detected resolving components of `file`
* @raise EISDIR if writing is requested and `file` names a directory
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @threadsafe

View file

@ -18,8 +18,9 @@
*/
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/errno.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/errors.h"
#include "libc/nt/synchronization.h"
#include "libc/sysv/errfuns.h"
@ -31,7 +32,7 @@ textwindows int sys_pause_nt(void) {
for (;;) {
if (_check_interrupts(false, g_fds.p)) {
return eintr();
return -1;
}
if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) {

View file

@ -17,9 +17,9 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sock/internal.h"
/**
@ -37,6 +37,7 @@
* However this has a tinier footprint and better logging.
*
* @return -1 w/ errno set to EINTR
* @cancellationpoint
* @see sigsuspend()
* @norestart
*/

View file

@ -21,7 +21,6 @@
#include "libc/calls/sig.internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/errno.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
@ -64,8 +63,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
if (sigmask) {
__sig_mask(SIG_SETMASK, sigmask, &oldmask);
}
if (_check_interrupts(false, g_fds.p)) {
rc = eintr();
if ((rc = _check_interrupts(false, g_fds.p))) {
goto ReturnPath;
}
@ -190,8 +188,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
}
// otherwise loop limitlessly for timeout to elapse while
// checking for signal delivery interrupts, along the way
if (_check_interrupts(false, g_fds.p)) {
rc = eintr();
if ((rc = _check_interrupts(false, g_fds.p))) {
goto ReturnPath;
}
}

View file

@ -55,6 +55,7 @@
* @return fds[𝑖].revents is always zero initializaed and then will
* be populated with POLL{IN,OUT,PRI,HUP,ERR,NVAL} if something
* was determined about the file descriptor
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @norestart

View file

@ -50,6 +50,7 @@
*
* @param timeout if null will block indefinitely
* @param sigmask may be null in which case no mask change happens
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @norestart

View file

@ -48,6 +48,7 @@
* @raise EIO if a complicated i/o error happened
* @raise EINTR if signal was delivered instead
* @see pwrite(), write()
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @vforksafe

View file

@ -108,6 +108,7 @@ static ssize_t Preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
* Reads with maximum generality.
*
* @return number of bytes actually read, or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @vforksafe
*/

View file

@ -42,6 +42,7 @@
* @return [1..size] bytes on success, or -1 w/ errno; noting zero is
* impossible unless size was passed as zero to do an error check
* @see pread(), write()
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @vforksafe

View file

@ -114,6 +114,7 @@ static ssize_t Pwritev(int fd, const struct iovec *iov, int iovlen,
* call using pwrite().
*
* @return number of bytes actually sent, or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @vforksafe
*/

View file

@ -53,7 +53,7 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
}
if (_check_interrupts(true, g_fds.p)) {
POLLTRACE("sys_read_nt interrupted");
return eintr();
return -1;
}
}
POLLTRACE("sys_read_nt ready to read");
@ -94,7 +94,7 @@ textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov,
uint32_t size;
size_t i, total;
if (opt_offset < -1) return einval();
if (_check_interrupts(true, fd)) return eintr();
if (_check_interrupts(true, fd)) return -1;
while (iovlen && !iov[0].iov_len) iov++, iovlen--;
if (iovlen) {
for (total = i = 0; i < iovlen; ++i) {

View file

@ -56,6 +56,7 @@
* or `SO_RCVTIMEO` is in play and the time interval elapsed
* @raise ENOBUFS is specified by POSIX
* @raise ENXIO is specified by POSIX
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @vforksafe

View file

@ -43,6 +43,7 @@
* performance boost in the case of a single small iovec.
*
* @return number of bytes actually read, or -1 w/ errno
* @cancellationpoint
* @restartable
*/
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {

View file

@ -17,15 +17,10 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/str/str.h"
/**
* Blocks all signals without strace logging.
*
* @param neu is new signal mask for process
* @return old signal mask
*/
sigset_t _sigblockall(void) {
sigset_t ss;
sigfillset(&ss);
memset(&ss, -1, sizeof(ss));
return _sigsetmask(ss);
}

View file

@ -75,6 +75,11 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
*uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs;
((sigaction_f)(_base + rva))(sig, &si2, &uc);
ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp;
ctx->uc_stack.ss_size = uc.uc_stack.ss_size;
ctx->uc_stack.ss_flags = uc.uc_stack.ss_flags;
__repmovsb(&ctx->uc_sigmask, &uc.uc_sigmask,
MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
ctx->uc_mcontext.rdi = uc.uc_mcontext.rdi;
ctx->uc_mcontext.rsi = uc.uc_mcontext.rsi;
ctx->uc_mcontext.rdx = uc.uc_mcontext.rdx;

View file

@ -76,6 +76,7 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
*g.uc.uc_mcontext.fpregs = *ctx->sc_fpstate;
}
((sigaction_f)(_base + rva))(sig, &g.si, &g.uc);
ctx->sc_mask = g.uc.uc_sigmask.__bits[0];
ctx->sc_rdi = g.uc.uc_mcontext.rdi;
ctx->sc_rsi = g.uc.uc_mcontext.rsi;
ctx->sc_rdx = g.uc.uc_mcontext.rdx;

View file

@ -501,6 +501,7 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
xnuctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp;
xnuctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
xnuctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
xnuctx->uc_sigmask = g.uc.uc_sigmask.__bits[0];
if (xnuctx->uc_mcontext) {
if (xnuctx->uc_mcsize >=
sizeof(struct __darwin_x86_exception_state64)) {

View file

@ -26,6 +26,7 @@
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
@ -59,7 +60,9 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
rc = efault();
} else if (IsMetal() || IsWindows()) {
rc = __sig_mask(how, opt_set, &old);
_check_interrupts(false, 0);
if (_weaken(__sig_check)) {
_weaken(__sig_check)(true);
}
} else {
rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0);
}

View file

@ -23,12 +23,6 @@
#include "libc/dce.h"
#include "libc/sysv/consts/sig.h"
/**
* Sets signal mask without strace logging.
*
* @param neu is new signal mask for process
* @return old signal mask
*/
sigset_t _sigsetmask(sigset_t neu) {
sigset_t res;
if (IsMetal() || IsWindows()) {

View file

@ -40,6 +40,7 @@
* @param ignore is a bitset of signals to block temporarily, which if
* NULL is equivalent to passing an empty signal set
* @return -1 w/ EINTR (or possibly EFAULT)
* @cancellationpoint
* @asyncsignalsafe
* @norestart
*/
@ -72,8 +73,7 @@ int sigsuspend(const sigset_t *ignore) {
ms = 0;
totoms = 0;
do {
if (_check_interrupts(false, g_fds.p)) {
rc = eintr();
if ((rc = _check_interrupts(false, g_fds.p))) {
break;
}
if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) {

View file

@ -40,6 +40,7 @@
* @raise EAGAIN if deadline expired
* @raise ENOSYS on Windows, XNU, OpenBSD, Metal
* @raise EFAULT if invalid memory was supplied
* @cancellationpoint
*/
int sigtimedwait(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout) {

View file

@ -27,6 +27,7 @@
* @raise EINTR if an asynchronous signal was delivered instead
* @raise ENOSYS on OpenBSD, XNU, and Windows
* @see sigtimedwait()
* @cancellationpoint
*/
int sigwaitinfo(const sigset_t *mask, siginfo_t *si) {
return sigtimedwait(mask, si, 0);

View file

@ -29,6 +29,7 @@
* this function shall return the number of unslept seconds rounded
* using the ceiling function
* @see clock_nanosleep()
* @cancellationpoint
* @asyncsignalsafe
* @norestart
*/

View file

@ -18,17 +18,18 @@
*/
#include "libc/calls/calls.h"
#include "libc/calls/state.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/statfs-meta.internal.h"
#include "libc/calls/struct/statfs.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/consts/at.h"
/**
* Returns information about filesystem.
* @return 0 on success, or -1 w/ errno
* @cancellationpoint
*/
int statfs(const char *path, struct statfs *sf) {
int rc;

View file

@ -18,6 +18,7 @@ char *sys_getcwd_xnu(char *, u64) hidden;
i32 __sys_dup3(i32, i32, i32) hidden;
i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
i32 __sys_fcntl(i32, i32, ...) hidden;
i32 __sys_fcntl_cp(i32, i32, ...) hidden;
i32 __sys_fstat(i32, void *) hidden;
i32 __sys_fstatat(i32, const char *, void *, i32) hidden;
i32 __sys_gettid(i64 *) hidden;
@ -43,7 +44,7 @@ i32 sys_fchmod(i32, u32) hidden;
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
i32 sys_fchown(i64, u32, u32) hidden;
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
i32 sys_fcntl(i32, i32, u64) hidden;
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) hidden;
i32 sys_fdatasync(i32) hidden;
i32 sys_flock(i32, i32) hidden;
i32 sys_fork(void) hidden;
@ -59,6 +60,7 @@ i32 sys_getresuid(u32 *, u32 *, u32 *) hidden;
i32 sys_getsid(i32) hidden;
i32 sys_gettid(void) hidden;
i32 sys_ioctl(i32, u64, ...) hidden;
i32 sys_ioctl_cp(i32, u64, ...) hidden;
i32 sys_issetugid(void) hidden;
i32 sys_kill(i32, i32, i32) hidden;
i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden;

View file

@ -40,6 +40,7 @@ static textwindows int sys_tcdrain_nt(int fd) {
* @raise EIO if process group of writer is orphoned, calling thread is
* not blocking `SIGTTOU`, and process isn't ignoring `SIGTTOU`
* @raise ENOSYS on bare metal
* @cancellationpoint
* @asyncsignalsafe
*/
int tcdrain(int fd) {
@ -47,7 +48,7 @@ int tcdrain(int fd) {
if (IsMetal()) {
rc = enosys();
} else if (!IsWindows()) {
rc = sys_ioctl(fd, TCSBRK, (void *)(intptr_t)1);
rc = sys_ioctl_cp(fd, TCSBRK, (void *)(intptr_t)1);
} else {
rc = sys_tcdrain_nt(fd);
}

View file

@ -58,6 +58,7 @@
* @raise ETXTBSY if `path` is an executable being executed
* @raise EROFS if `path` is on a read-only filesystem
* @raise ENOSYS on bare metal
* @cancellationpoint
* @see ftruncate()
* @threadsafe
*/

View file

@ -27,6 +27,7 @@
* @return 0 on success, or -1 w/ errno
* @raise EINTR if a signal was delivered while sleeping
* @see clock_nanosleep()
* @cancellationpoint
* @norestart
*/
int usleep(uint32_t micros) {

View file

@ -24,6 +24,7 @@
* @param opt_out_wstatus optionally returns status code, and *wstatus
* may be inspected using WEEXITSTATUS(), etc.
* @return process id of terminated child or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @vforksafe

View file

@ -27,6 +27,7 @@
* @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc.
* @param opt_out_rusage optionally returns accounting data
* @return process id of terminated child or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable
*/

View file

@ -48,15 +48,15 @@
static textwindows int sys_wait4_nt_impl(int pid, int *opt_out_wstatus,
int options,
struct rusage *opt_out_rusage) {
int pids[64];
int64_t handle;
int rc, pids[64];
int64_t handles[64];
uint32_t dwExitCode;
bool shouldinterrupt;
uint32_t i, j, base, count, timeout;
struct NtProcessMemoryCountersEx memcount;
struct NtFileTime createfiletime, exitfiletime, kernelfiletime, userfiletime;
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
__fds_lock();
if (pid != -1 && pid != 0) {
if (pid < 0) {
@ -94,7 +94,7 @@ static textwindows int sys_wait4_nt_impl(int pid, int *opt_out_wstatus,
}
__fds_unlock();
for (;;) {
if (_check_interrupts(true, 0)) return eintr();
if (_check_interrupts(true, 0)) return -1;
dwExitCode = kNtStillActive;
if (options & WNOHANG) {
i = WaitForMultipleObjects(count, handles, false, 0);

View file

@ -17,11 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/rusage.internal.h"
#include "libc/calls/wait4.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/errfuns.h"
/**
@ -34,6 +34,7 @@
* @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc.
* @param opt_out_rusage optionally returns accounting data
* @return process id of terminated child or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable
*/

View file

@ -27,6 +27,7 @@
* may be inspected using WEXITSTATUS(), etc.
* @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc.
* @return process id of terminated child or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable
*/

View file

@ -57,6 +57,7 @@
* as a general possibility; whereas other system don't specify it
* @raise ENXIO is specified only by POSIX and XNU when a request is
* made of a nonexistent device or outside device capabilities
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @vforksafe

View file

@ -47,6 +47,7 @@
* call using write().
*
* @return number of bytes actually handed off, or -1 w/ errno
* @cancellationpoint
* @restartable
*/
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {

View file

@ -62,6 +62,7 @@ kSignalNames:
.e SIGIO,"SIGIO"
.e SIGSYS,"SIGSYS"
.e SIGINFO,"SIGINFO"
.e SIGCANCEL,"SIGCANCEL"
.e SIGRTMAX,"SIGRTMAX"
.e SIGRTMIN,"SIGRTMIN"
.e SIGEMT,"SIGEMT"

View file

@ -33,12 +33,7 @@ int sigaddset(sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
if (1 <= sig && sig <= _NSIG) {
if (
#define M(x) sig != x &&
#include "libc/intrin/sigisprecious.inc"
1) {
set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
}
set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
}
return 0;
} else {

View file

@ -1,3 +1,4 @@
M(SIGKILL)
M(SIGABRT)
M(SIGSTOP)
M(SIGCANCEL)

View file

@ -34,6 +34,7 @@
* @param addr needs to be 4096-byte page aligned
* @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE
* @return 0 on success or -1 w/ errno
* @cancellationpoint
*/
int msync(void *addr, size_t size, int flags) {
int rc;

View file

@ -32,10 +32,10 @@
textwindows int sys_accept_nt(struct Fd *fd, void *addr, uint32_t *addrsize,
int flags) {
int64_t h;
int client, oflags;
int rc, client, oflags;
struct SockFd *sockfd, *sockfd2;
sockfd = (struct SockFd *)fd->extra;
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
for (;;) {
if (!WSAPoll(&(struct sys_pollfd_nt){fd->handle, POLLIN}, 1,
__SIG_POLLING_INTERVAL_MS)) {

View file

@ -26,6 +26,7 @@
* @param out_addr will receive the remote address
* @param inout_addrsize provides and receives addr's byte length
* @return client fd which needs close(), or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -36,6 +36,7 @@
* @param flags can have SOCK_{CLOEXEC,NONBLOCK}, which may apply to
* both the newly created socket and the server one
* @return client fd which needs close(), or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -35,6 +35,7 @@
* also means getsockname() can be called to retrieve routing details.
*
* @return 0 on success or -1 w/ errno
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -1499,6 +1499,7 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) {
* @param maxevents is array length of events
* @param timeoutms is milliseconds, 0 to not block, or -1 for forever
* @return number of events stored, 0 on timeout, or -1 w/ errno
* @cancellationpoint
* @norestart
*/
int epoll_wait(int epfd, struct epoll_event *events, int maxevents,

View file

@ -16,12 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/select.h"
#include "libc/sysv/errfuns.h"
@ -44,6 +44,11 @@
*
* This system call is supported on all platforms. It's like select()
* except that it atomically changes the sigprocmask() during the op.
*
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @norestart
*/
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask) {

View file

@ -34,7 +34,7 @@ textwindows ssize_t sys_recv_nt(struct Fd *fd, const struct iovec *iov,
struct SockFd *sockfd;
struct NtIovec iovnt[16];
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
err = errno;
if (!WSARecv(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got, &flags,
&overlapped, NULL)) {

View file

@ -35,7 +35,7 @@ textwindows ssize_t sys_recvfrom_nt(struct Fd *fd, const struct iovec *iov,
struct SockFd *sockfd;
struct NtIovec iovnt[16];
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
err = errno;
if (!WSARecvFrom(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got,
&flags, opt_out_srcaddr, opt_inout_srcaddrsize, &overlapped,

View file

@ -44,6 +44,7 @@
* @return number of bytes received, 0 on remote close, or -1 w/ errno
* @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable),
* EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc.
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -41,6 +41,7 @@
* @return number of bytes received, or -1 w/ errno
* @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable),
* EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc.
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -16,11 +16,11 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/select.h"
#include "libc/sysv/errfuns.h"
@ -31,6 +31,11 @@
* This system call is supported on all platforms. However, on Windows,
* this is polyfilled to translate into poll(). So it's recommended that
* poll() be used instead.
*
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @norestart
*/
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout) {

View file

@ -30,7 +30,7 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
struct SockFd *sockfd;
struct NtIovec iovnt[16];
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
if (!WSASend(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &sent,
flags, &overlapped, NULL)) {
rc = sent;

View file

@ -43,6 +43,7 @@
// sendfile() isn't specified as raising eintr
static textwindows int SendfileBlock(int64_t handle,
struct NtOverlapped *overlapped) {
int rc;
uint32_t i, got, flags = 0;
if (WSAGetLastError() != kNtErrorIoPending &&
WSAGetLastError() != WSAEINPROGRESS) {
@ -56,7 +57,7 @@ static textwindows int SendfileBlock(int64_t handle,
NTTRACE("WSAWaitForMultipleEvents failed %lm");
return __winsockerr();
} else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) {
_check_interrupts(true, g_fds.p);
if (_check_interrupts(true, g_fds.p)) return -1;
#if _NTTRACE
POLLTRACE("WSAWaitForMultipleEvents...");
#endif

View file

@ -43,6 +43,7 @@
* @return number of bytes transmitted, or -1 w/ errno
* @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable),
* EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc.
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -31,7 +31,7 @@ textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
struct SockFd *sockfd;
struct NtIovec iovnt[16];
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
if (_check_interrupts(true, g_fds.p)) return eintr();
if (_check_interrupts(true, g_fds.p)) return -1;
if (!WSASendTo(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen),
&sent, flags, opt_in_addr, in_addrsize, &overlapped, NULL)) {
rc = sent;

View file

@ -49,6 +49,7 @@
* @return number of bytes transmitted, or -1 w/ errno
* @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable),
* EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc.
* @cancellationpoint
* @asyncsignalsafe
* @restartable (unless SO_RCVTIMEO)
*/

View file

@ -28,6 +28,7 @@
textwindows int __wsablock(int64_t handle, struct NtOverlapped *overlapped,
uint32_t *flags, bool restartable,
uint32_t timeout) {
int rc;
uint32_t i, got;
if (WSAGetLastError() != kNtErrorIoPending) {
NTTRACE("sock i/o failed %lm");
@ -41,7 +42,7 @@ textwindows int __wsablock(int64_t handle, struct NtOverlapped *overlapped,
return __winsockerr();
} else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) {
if (_check_interrupts(restartable, g_fds.p)) {
return eintr();
return -1;
}
if (timeout) {
if (timeout <= __SIG_POLLING_INTERVAL_MS) {

View file

@ -255,14 +255,20 @@ static textwindows dontinline struct dirent *readdir_nt(DIR *dir) {
*
* @returns newly allocated DIR object, or NULL w/ errno
* @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM
* @cancellationpoint
* @see glob()
*/
DIR *opendir(const char *name) {
int fd;
DIR *res;
int fd, rc;
struct stat st;
struct Zipos *zip;
struct ZiposUri zipname;
if (_weaken(pthread_testcancel_np) &&
(rc = _weaken(pthread_testcancel_np)())) {
errno = rc;
return 0;
}
if (!name || (IsAsan() && !__asan_is_valid_str(name))) {
efault();
res = 0;
@ -271,20 +277,21 @@ DIR *opendir(const char *name) {
if (_weaken(__zipos_stat)(&zipname, &st) != -1) {
if (S_ISDIR(st.st_mode)) {
zip = _weaken(__zipos_get)();
res = calloc(1, sizeof(DIR));
res->iszip = true;
res->fd = -1;
res->zip.offset = GetZipCdirOffset(zip->cdir);
res->zip.records = GetZipCdirRecords(zip->cdir);
res->zip.prefix = malloc(zipname.len + 2);
memcpy(res->zip.prefix, zipname.path, zipname.len);
if (zipname.len && res->zip.prefix[zipname.len - 1] != '/') {
res->zip.prefix[zipname.len++] = '/';
if ((res = calloc(1, sizeof(DIR)))) {
res->iszip = true;
res->fd = -1;
res->zip.offset = GetZipCdirOffset(zip->cdir);
res->zip.records = GetZipCdirRecords(zip->cdir);
res->zip.prefix = malloc(zipname.len + 2);
memcpy(res->zip.prefix, zipname.path, zipname.len);
if (zipname.len && res->zip.prefix[zipname.len - 1] != '/') {
res->zip.prefix[zipname.len++] = '/';
}
res->zip.prefix[zipname.len] = '\0';
res->zip.prefixlen = zipname.len;
}
res->zip.prefix[zipname.len] = '\0';
res->zip.prefixlen = zipname.len;
} else {
errno = ENOTDIR;
enotdir();
res = 0;
}
} else {

View file

@ -70,6 +70,7 @@ static bool have_getrandom;
* @note this function takes around 900 cycles
* @raise EINVAL if `f` is invalid
* @raise ENOSYS on bare metal
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @vforksafe

View file

@ -19,6 +19,7 @@
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/intrin/weaken.h"
#include "libc/paths.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/internal.h"
@ -27,6 +28,7 @@
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
/**
* Spawns subprocess and returns pipe stream.
@ -35,11 +37,12 @@
* Bourne-like syntax on all platforms including Windows.
*
* @see pclose()
* @cancellationpoint
* @threadsafe
*/
FILE *popen(const char *cmdline, const char *mode) {
FILE *f;
int e, pid, dir, flags, pipefds[2];
int e, rc, pid, dir, flags, pipefds[2];
flags = fopenflags(mode);
if ((flags & O_ACCMODE) == O_RDONLY) {
dir = 0;
@ -49,6 +52,11 @@ FILE *popen(const char *cmdline, const char *mode) {
einval();
return NULL;
}
if (_weaken(pthread_testcancel_np) &&
(rc = _weaken(pthread_testcancel_np)())) {
errno = rc;
return 0;
}
if (pipe2(pipefds, O_CLOEXEC) == -1) return NULL;
if ((f = fdopen(pipefds[dir], mode))) {
switch ((pid = fork())) {

View file

@ -25,6 +25,7 @@
#include "libc/stdio/posix_spawn.h"
#include "libc/stdio/posix_spawn.internal.h"
#include "libc/sysv/consts/sig.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
static int RunFileActions(struct _posix_faction *a) {
@ -67,6 +68,7 @@ static int RunFileActions(struct _posix_faction *a) {
* @param envp is environment variables, or `environ` if null
* @return 0 on success or error number on failure
* @see posix_spawnp() for `$PATH` searching
* @cancellationpoint
* @tlsrequired
* @threadsafe
*/
@ -79,6 +81,9 @@ int posix_spawn(int *pid, const char *path,
int s, child, policy;
struct sched_param param;
struct sigaction dfl = {0};
if (_weaken(pthread_testcancel)) {
_weaken(pthread_testcancel)();
}
if (!(child = vfork())) {
if (attrp && *attrp) {
posix_spawnattr_getflags(attrp, &flags);

View file

@ -21,12 +21,14 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/weaken.h"
#include "libc/log/log.h"
#include "libc/paths.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/sig.h"
#include "libc/thread/thread.h"
/**
* Launches program with system command interpreter.
@ -37,6 +39,7 @@
* @param cmdline is an interpreted Turing-complete command
* @return -1 if child process couldn't be created, otherwise a wait
* status that can be accessed using macros like WEXITSTATUS(s)
* @cancellationpoint
* @threadsafe
*/
int system(const char *cmdline) {
@ -44,6 +47,9 @@ int system(const char *cmdline) {
sigset_t chldmask, savemask;
struct sigaction ignore, saveint, savequit;
if (!cmdline) return 1;
if (_weaken(pthread_testcancel)) {
_weaken(pthread_testcancel)();
}
ignore.sa_flags = 0;
ignore.sa_handler = SIG_IGN;
sigemptyset(&ignore.sa_mask);

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_accept,0x01e01e21d201e02b,globl,hidden
.scall __sys_accept,0x81e81ea1d281e82b,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_accept4,0xfff05d21dffff120,globl,hidden
.scall __sys_accept4,0xfff85da1dffff920,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_connect,0x062062062206202a,globl,hidden
.scall __sys_connect,0x862862862286282a,globl,hidden

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_fcntl_cp,0x85c85c85c285c848,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_openat,0x1d41411f321cf101,globl,hidden
.scall __sys_openat,0x9d49419f329cf901,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_wait4,0x1c100b007200703d,globl,hidden
.scall __sys_wait4,0x9c180b807280783d,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall posix_fallocate,0x1dffff212fffffff,globl,hidden
.scall posix_fallocate,0x9dffffa12fffffff,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_clock_nanosleep,0x1ddfff0f4ffff0e6,globl,hidden
.scall sys_clock_nanosleep,0x9ddfff8f4ffff8e6,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_epoll_wait,0xfffffffffffff0e8,globl,hidden
.scall sys_epoll_wait,0xfffffffffffff8e8,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fallocate,0xfffffffffffff11d,globl
.scall sys_fallocate,0xfffffffffffff91d,globl

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fdatasync,0x0f105f22620bb04b,globl,hidden
.scall sys_fdatasync,0x8f185fa2628bb84b,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_flock,0x0830830832083049,globl,hidden
.scall sys_flock,0x8838838832883849,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fstatfs,0x09e04022c215a08a,globl,hidden
.scall sys_fstatfs,0x89e840a2c295a88a,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fsync,0x05f05f05f205f04a,globl,hidden
.scall sys_fsync,0x85f85f85f285f84a,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_ftruncate,0x0c90c91e020c904d,globl,hidden
.scall sys_ftruncate,0x8c98c99e028c984d,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_getrandom,0xfff00723321f413e,globl,hidden
.scall sys_getrandom,0xfff807a3329f493e,globl,hidden

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_ioctl_cp,0x8368368362836810,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_msgrcv,0x0e30e30e32105046,globl
.scall sys_msgrcv,0x8e38e38e32905846,globl

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_msgsnd,0x0e20e20e22104045,globl
.scall sys_msgsnd,0x8e28e28e22904845,globl

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_msync,0x115100041204101a,globl,hidden
.scall sys_msync,0x915900841284181a,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_nanosleep,0x1ae05b0f0ffff023,globl,hidden
.scall sys_nanosleep,0x9ae85b8f0ffff823,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_open,0x0050050052005002,globl,hidden
.scall sys_open,0x8058058052805802,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_poll,0x0d10fc0d120e6007,globl,hidden
.scall sys_poll,0x8d18fc8d128e6807,globl,hidden

Some files were not shown because too many files have changed in this diff Show more