mirror of
git://git.musl-libc.org/musl
synced 2025-03-06 20:48:29 +01:00
add framework to support archs without a native wait4 syscall
this commit should make no codegen change for existing archs, but is a prerequisite for new archs including riscv32. the wait4 emulation backend provides both cancellable and non-cancellable variants because waitpid is required to be a cancellation point, but all of our other uses are not, and most of them cannot be. based on patch by Stefan O'Rear.
This commit is contained in:
parent
7020e85fd7
commit
19563e1850
6 changed files with 71 additions and 4 deletions
55
src/internal/emulate_wait4.c
Normal file
55
src/internal/emulate_wait4.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <sys/wait.h>
|
||||
#include "syscall.h"
|
||||
|
||||
#ifndef SYS_wait4
|
||||
hidden long __emulate_wait4(int 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:
|
||||
/* see ptrace(2); the high bits of si_status can contain */
|
||||
/* PTRACE_EVENT_ values which must be preserved */
|
||||
sw = (info.si_status << 8) + 0x7f;
|
||||
break;
|
||||
}
|
||||
*status = sw;
|
||||
}
|
||||
|
||||
return info.si_pid;
|
||||
}
|
||||
#endif
|
|
@ -391,6 +391,18 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a,
|
|||
#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)
|
||||
#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))
|
||||
|
||||
#ifdef SYS_wait4
|
||||
#define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d)
|
||||
#define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d)
|
||||
#else
|
||||
hidden long __emulate_wait4(int, int *, int, void *, int);
|
||||
#define __sys_wait4(a,b,c,d) __emulate_wait4(a,b,c,d,0)
|
||||
#define __sys_wait4_cp(a,b,c,d) __emulate_wait4(a,b,c,d,1)
|
||||
#endif
|
||||
|
||||
#define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d))
|
||||
#define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d))
|
||||
|
||||
hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
|
||||
|
||||
hidden void *__vdsosym(const char *, const char *);
|
||||
|
|
|
@ -26,7 +26,7 @@ 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;
|
||||
r = __syscall(SYS_wait4, pid, status, options, dest);
|
||||
r = __sys_wait4(pid, status, options, dest);
|
||||
if (r>0 && ru && sizeof(time_t) > sizeof(long)) {
|
||||
long kru[4];
|
||||
memcpy(kru, dest, 4*sizeof(long));
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
pid_t waitpid(pid_t pid, int *status, int options)
|
||||
{
|
||||
return syscall_cp(SYS_wait4, pid, status, options, 0);
|
||||
return sys_wait4_cp(pid, status, options, 0);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ int pclose(FILE *f)
|
|||
int status, r;
|
||||
pid_t pid = f->pipe_pid;
|
||||
fclose(f);
|
||||
while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
|
||||
while ((r=__sys_wait4(pid, &status, 0, 0)) == -EINTR);
|
||||
if (r<0) return __syscall_ret(r);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ 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]);
|
||||
__syscall(SYS_wait4, pid, &status, __WCLONE, 0);
|
||||
__sys_wait4(pid, &status, __WCLONE, 0);
|
||||
|
||||
__restore_sigs(&set);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue