|
Message-Id: <20200903112309.102601-8-sorear@fastmail.com> Date: Thu, 3 Sep 2020 07:23:02 -0400 From: Stefan O'Rear <sorear@...tmail.com> To: musl@...ts.openwall.com Cc: Stefan O'Rear <sorear@...tmail.com> Subject: [PATCH 07/14] Emulate wait4 using waitid riscv32 and future architectures lack wait4. --- src/internal/wait4_waitid.h | 1 + src/linux/__wait4_waitid.c | 52 +++++++++++++++++++++++++++++++++++++ src/linux/wait4.c | 5 ++++ src/process/waitpid.c | 6 +++++ src/stdio/pclose.c | 6 +++++ src/unistd/faccessat.c | 6 ++++- 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/internal/wait4_waitid.h create mode 100644 src/linux/__wait4_waitid.c diff --git a/src/internal/wait4_waitid.h b/src/internal/wait4_waitid.h new file mode 100644 index 00000000..0ef1b9b1 --- /dev/null +++ b/src/internal/wait4_waitid.h @@ -0,0 +1 @@ +hidden pid_t __wait4_waitid(pid_t pid, int *status, int options, void *kru, int cp); diff --git a/src/linux/__wait4_waitid.c b/src/linux/__wait4_waitid.c new file mode 100644 index 00000000..208f1631 --- /dev/null +++ b/src/linux/__wait4_waitid.c @@ -0,0 +1,52 @@ +#include <sys/wait.h> +#include "syscall.h" +#include "wait4_waitid.h" + +hidden pid_t __wait4_waitid(pid_t pid, int *status, int options, void *kru, int cp) +{ + idtype_t t; + int r; + siginfo_t info; + + info.si_pid = 0; + if (pid < -1) { + t = P_PGID; + pid = -pid; + } else if (pid == -1) { + t = P_ALL; + } else if (pid == 0) { + t = P_PGID; + } else { + t = P_PID; + } + + if (cp) r = __syscall_cp(SYS_waitid, t, pid, &info, options|WEXITED, kru); + else r = __syscall(SYS_waitid, t, pid, &info, options|WEXITED, kru); + + if (r<0) return r; + + if (info.si_pid && status) { + int sw=0; + switch (info.si_code) { + case CLD_CONTINUED: + sw = 0xffff; + break; + case CLD_DUMPED: + sw = info.si_status&0x7f | 0x80; + break; + case CLD_EXITED: + sw = (info.si_status&0xff) << 8; + break; + case CLD_KILLED: + sw = info.si_status&0x7f; + break; + case CLD_STOPPED: + case CLD_TRAPPED: + sw = ((info.si_status&0xff) << 8) + 0x7f; + break; + } + *status = sw; + } + + return info.si_pid; +} diff --git a/src/linux/wait4.c b/src/linux/wait4.c index 83650e34..e4d3a053 100644 --- a/src/linux/wait4.c +++ b/src/linux/wait4.c @@ -4,6 +4,7 @@ #include <string.h> #include <errno.h> #include "syscall.h" +#include "wait4_waitid.h" pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru) { @@ -26,7 +27,11 @@ pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru) } #endif char *dest = ru ? (char *)&ru->ru_maxrss - 4*sizeof(long) : 0; +#ifdef SYS_wait4 r = __syscall(SYS_wait4, pid, status, options, dest); +#else + r = __wait4_waitid(pid, status, options, dest, 0); +#endif if (r>0 && ru && sizeof(time_t) > sizeof(long)) { long kru[4]; memcpy(kru, dest, 4*sizeof(long)); diff --git a/src/process/waitpid.c b/src/process/waitpid.c index 1b65bf05..49668822 100644 --- a/src/process/waitpid.c +++ b/src/process/waitpid.c @@ -1,7 +1,13 @@ +#define _GNU_SOURCE #include <sys/wait.h> #include "syscall.h" +#include "wait4_waitid.h" pid_t waitpid(pid_t pid, int *status, int options) { +#ifdef SYS_wait4 return syscall_cp(SYS_wait4, pid, status, options, 0); +#else + return __syscall_ret(__wait4_waitid(pid, status, options, 0, 1)); +#endif } diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c index 080a4262..79e3d1d5 100644 --- a/src/stdio/pclose.c +++ b/src/stdio/pclose.c @@ -1,4 +1,6 @@ #include "stdio_impl.h" +#include <sys/wait.h> +#include "wait4_waitid.h" #include <errno.h> #include <unistd.h> @@ -7,7 +9,11 @@ int pclose(FILE *f) int status, r; pid_t pid = f->pipe_pid; fclose(f); +#ifdef SYS_wait4 while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR); +#else + while ((r=__wait4_waitid(pid, &status, 0, 0, 0)) == -EINTR); +#endif if (r<0) return __syscall_ret(r); return status; } diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c index 76bbd4c7..8bf34995 100644 --- a/src/unistd/faccessat.c +++ b/src/unistd/faccessat.c @@ -34,7 +34,6 @@ int faccessat(int fd, const char *filename, int amode, int flag) char stack[1024]; sigset_t set; pid_t pid; - int status; int ret, p[2]; if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY); @@ -48,7 +47,12 @@ int faccessat(int fd, const char *filename, int amode, int flag) if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret)) ret = -EBUSY; __syscall(SYS_close, p[0]); +#ifdef SYS_wait4 + int status; __syscall(SYS_wait4, pid, &status, __WCLONE, 0); +#else + __syscall(SYS_waitid, P_PID, pid, &(siginfo_t){0}, __WCLONE|WEXITED, 0); +#endif __restore_sigs(&set); -- 2.25.4
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.