Commit 65894e60 authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: Handles correctly errno == EINTR in lots of places.

On various places (mostly waitpid() calls) this patch makes sure that if errno
== EINTR on return, then the syscall is endlessly retried.  It also defines a
simple generic way to do this.

Signed-off-by: <blaisorblade_spam@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 38cbcf22
...@@ -175,7 +175,8 @@ static int change_tramp(char **argv, char *output, int output_len) ...@@ -175,7 +175,8 @@ static int change_tramp(char **argv, char *output, int output_len)
os_close_file(fds[1]); os_close_file(fds[1]);
read_output(fds[0], output, output_len); read_output(fds[0], output, output_len);
waitpid(pid, NULL, 0);
CATCH_EINTR(err = waitpid(pid, NULL, 0));
return(pid); return(pid);
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <stddef.h> #include <stddef.h>
#include <sched.h> #include <sched.h>
#include <string.h> #include <string.h>
#include <sys/errno.h> #include <errno.h>
#include <sys/termios.h> #include <sys/termios.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/signal.h> #include <sys/signal.h>
...@@ -100,7 +100,9 @@ static int slip_tramp(char **argv, int fd) ...@@ -100,7 +100,9 @@ static int slip_tramp(char **argv, int fd)
printk("%s", output); printk("%s", output);
kfree(output); kfree(output);
} }
if(waitpid(pid, &status, 0) < 0) err = errno; CATCH_EINTR(err = waitpid(pid, &status, 0));
if(err < 0)
err = errno;
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
printk("'%s' didn't exit with status 0\n", argv[0]); printk("'%s' didn't exit with status 0\n", argv[0]);
err = -EINVAL; err = -EINVAL;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <stddef.h> #include <stddef.h>
#include <sched.h> #include <sched.h>
#include <string.h> #include <string.h>
#include <sys/errno.h> #include <errno.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/signal.h> #include <sys/signal.h>
#include "user_util.h" #include "user_util.h"
...@@ -113,13 +113,13 @@ static void slirp_close(int fd, void *data) ...@@ -113,13 +113,13 @@ static void slirp_close(int fd, void *data)
} }
#endif #endif
err = waitpid(pri->pid, &status, WNOHANG); CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
if(err<0) { if(err < 0) {
printk("slirp_close: waitpid returned %d\n", errno); printk("slirp_close: waitpid returned %d\n", errno);
return; return;
} }
if(err==0) { if(err == 0) {
printk("slirp_close: process %d has not exited\n"); printk("slirp_close: process %d has not exited\n");
return; return;
} }
......
...@@ -92,6 +92,7 @@ extern void arch_init_thread(void); ...@@ -92,6 +92,7 @@ extern void arch_init_thread(void);
extern int __raw(int fd, int complain, int now); extern int __raw(int fd, int complain, int now);
#define raw(fd, complain) __raw((fd), (complain), 1) #define raw(fd, complain) __raw((fd), (complain), 1)
#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR)
#endif #endif
/* /*
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "sysdep/sigcontext.h" #include "sysdep/sigcontext.h"
#include "frame_user.h" #include "frame_user.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h"
#include "ptrace_user.h" #include "ptrace_user.h"
#include "os.h" #include "os.h"
...@@ -40,7 +41,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp, ...@@ -40,7 +41,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
/* Wait for it to stop itself and continue it with a SIGUSR1 to force /* Wait for it to stop itself and continue it with a SIGUSR1 to force
* it into the signal handler. * it into the signal handler.
*/ */
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0){ if(n < 0){
printf("capture_stack : waitpid failed - errno = %d\n", errno); printf("capture_stack : waitpid failed - errno = %d\n", errno);
exit(1); exit(1);
...@@ -60,7 +61,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp, ...@@ -60,7 +61,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
* At this point, the handler has stuffed the addresses of * At this point, the handler has stuffed the addresses of
* sig, sc, and SA_RESTORER in raw. * sig, sc, and SA_RESTORER in raw.
*/ */
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0){ if(n < 0){
printf("capture_stack : waitpid failed - errno = %d\n", errno); printf("capture_stack : waitpid failed - errno = %d\n", errno);
exit(1); exit(1);
...@@ -82,7 +83,8 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp, ...@@ -82,7 +83,8 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
errno); errno);
exit(1); exit(1);
} }
if(waitpid(pid, &status, 0) < 0){ CATCH_EINTR(n = waitpid(pid, &status, 0));
if(n < 0){
printf("capture_stack : waitpid failed - errno = %d\n", errno); printf("capture_stack : waitpid failed - errno = %d\n", errno);
exit(1); exit(1);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include "user.h" #include "user.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h"
#include "os.h" #include "os.h"
struct helper_data { struct helper_data {
...@@ -96,7 +97,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, ...@@ -96,7 +97,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
goto out_kill; goto out_kill;
} }
else if(n != 0){ else if(n != 0){
waitpid(pid, NULL, 0); CATCH_EINTR(n = waitpid(pid, NULL, 0));
pid = -errno; pid = -errno;
} }
......
...@@ -125,7 +125,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, ...@@ -125,7 +125,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
/* Start the process and wait for it to kill itself */ /* Start the process and wait for it to kill itself */
new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
if(new_pid < 0) return(-errno); if(new_pid < 0) return(-errno);
while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ; CATCH_EINTR(err = waitpid(new_pid, &status, 0));
if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
errno); errno);
if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
...@@ -171,7 +171,7 @@ static int start_ptraced_child(void **stack_out) ...@@ -171,7 +171,7 @@ static int start_ptraced_child(void **stack_out)
pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
if(pid < 0) if(pid < 0)
panic("check_ptrace : clone failed, errno = %d", errno); panic("check_ptrace : clone failed, errno = %d", errno);
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0) if(n < 0)
panic("check_ptrace : wait failed, errno = %d", errno); panic("check_ptrace : wait failed, errno = %d", errno);
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
...@@ -188,7 +188,7 @@ static void stop_ptraced_child(int pid, void *stack, int exitcode) ...@@ -188,7 +188,7 @@ static void stop_ptraced_child(int pid, void *stack, int exitcode)
if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", errno); panic("check_ptrace : ptrace failed, errno = %d", errno);
n = waitpid(pid, &status, 0); CATCH_EINTR(n = waitpid(pid, &status, 0));
if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
panic("check_ptrace : child exited with status 0x%x", status); panic("check_ptrace : child exited with status 0x%x", status);
...@@ -226,7 +226,8 @@ static void __init check_sysemu(void) ...@@ -226,7 +226,8 @@ static void __init check_sysemu(void)
if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) {
struct user_regs_struct regs; struct user_regs_struct regs;
if (waitpid(pid, &status, WUNTRACED) < 0) CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if (n < 0)
panic("check_ptrace : wait failed, errno = %d", errno); panic("check_ptrace : wait failed, errno = %d", errno);
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
panic("check_ptrace : expected SIGTRAP, " panic("check_ptrace : expected SIGTRAP, "
...@@ -267,7 +268,7 @@ void __init check_ptrace(void) ...@@ -267,7 +268,7 @@ void __init check_ptrace(void)
if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", panic("check_ptrace : ptrace failed, errno = %d",
errno); errno);
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0) if(n < 0)
panic("check_ptrace : wait failed, errno = %d", errno); panic("check_ptrace : wait failed, errno = %d", errno);
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include "user.h" #include "user.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h"
#include "os.h" #include "os.h"
#include "time_user.h" #include "time_user.h"
...@@ -26,7 +27,7 @@ static int user_thread_tramp(void *arg) ...@@ -26,7 +27,7 @@ static int user_thread_tramp(void *arg)
int user_thread(unsigned long stack, int flags) int user_thread(unsigned long stack, int flags)
{ {
int pid, status; int pid, status, err;
pid = clone(user_thread_tramp, (void *) stack_sp(stack), pid = clone(user_thread_tramp, (void *) stack_sp(stack),
flags | CLONE_FILES | SIGCHLD, NULL); flags | CLONE_FILES | SIGCHLD, NULL);
...@@ -35,7 +36,8 @@ int user_thread(unsigned long stack, int flags) ...@@ -35,7 +36,8 @@ int user_thread(unsigned long stack, int flags)
return(pid); return(pid);
} }
if(waitpid(pid, &status, WUNTRACED) < 0){ CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if(err < 0){
printk("user_thread - waitpid failed, errno = %d\n", errno); printk("user_thread - waitpid failed, errno = %d\n", errno);
return(-errno); return(-errno);
} }
......
...@@ -81,7 +81,7 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu ...@@ -81,7 +81,7 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
panic("handle_trap - continuing to end of syscall failed, " panic("handle_trap - continuing to end of syscall failed, "
"errno = %d\n", errno); "errno = %d\n", errno);
err = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
panic("handle_trap - failed to wait at end of syscall, " panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status); "errno = %d, status = %d\n", errno, status);
...@@ -121,7 +121,7 @@ void start_userspace(int cpu) ...@@ -121,7 +121,7 @@ void start_userspace(int cpu)
panic("start_userspace : clone failed, errno = %d", errno); panic("start_userspace : clone failed, errno = %d", errno);
do { do {
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0) if(n < 0)
panic("start_userspace : wait failed, errno = %d", panic("start_userspace : wait failed, errno = %d",
errno); errno);
...@@ -154,7 +154,7 @@ void userspace(union uml_pt_regs *regs) ...@@ -154,7 +154,7 @@ void userspace(union uml_pt_regs *regs)
panic("userspace - PTRACE_%s failed, errno = %d\n", panic("userspace - PTRACE_%s failed, errno = %d\n",
local_using_sysemu ? "SYSEMU" : "SYSCALL", errno); local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
while(1){ while(1){
err = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if(err < 0) if(err < 0)
panic("userspace - waitpid failed, errno = %d\n", panic("userspace - waitpid failed, errno = %d\n",
errno); errno);
......
...@@ -32,7 +32,14 @@ void kill_child_dead(int pid) ...@@ -32,7 +32,14 @@ void kill_child_dead(int pid)
{ {
kill(pid, SIGKILL); kill(pid, SIGKILL);
kill(pid, SIGCONT); kill(pid, SIGCONT);
while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT); do {
int n;
CATCH_EINTR(n = waitpid(pid, NULL, 0));
if (n > 0)
kill(pid, SIGCONT);
else
break;
} while(1);
} }
/* Unlocked - don't care if this is a bit off */ /* Unlocked - don't care if this is a bit off */
......
...@@ -19,13 +19,18 @@ ...@@ -19,13 +19,18 @@
void do_exec(int old_pid, int new_pid) void do_exec(int old_pid, int new_pid)
{ {
unsigned long regs[FRAME_SIZE]; unsigned long regs[FRAME_SIZE];
int err;
if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) || if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
(ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) || (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
(waitpid(new_pid, 0, WUNTRACED) < 0))
tracer_panic("do_exec failed to attach proc - errno = %d", tracer_panic("do_exec failed to attach proc - errno = %d",
errno); errno);
CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
if (err < 0)
tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
errno);
if(ptrace_getregs(old_pid, regs) < 0) if(ptrace_getregs(old_pid, regs) < 0)
tracer_panic("do_exec failed to get registers - errno = %d", tracer_panic("do_exec failed to get registers - errno = %d",
errno); errno);
......
...@@ -272,7 +272,7 @@ void fake_child_exit(void) ...@@ -272,7 +272,7 @@ void fake_child_exit(void)
child_proxy(1, W_EXITCODE(0, 0)); child_proxy(1, W_EXITCODE(0, 0));
while(debugger.waiting == 1){ while(debugger.waiting == 1){
pid = waitpid(debugger.pid, &status, WUNTRACED); CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
if(pid != debugger.pid){ if(pid != debugger.pid){
printk("fake_child_exit - waitpid failed, " printk("fake_child_exit - waitpid failed, "
"errno = %d\n", errno); "errno = %d\n", errno);
...@@ -280,7 +280,7 @@ void fake_child_exit(void) ...@@ -280,7 +280,7 @@ void fake_child_exit(void)
} }
debugger_proxy(status, debugger.pid); debugger_proxy(status, debugger.pid);
} }
pid = waitpid(debugger.pid, &status, WUNTRACED); CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
if(pid != debugger.pid){ if(pid != debugger.pid){
printk("fake_child_exit - waitpid failed, " printk("fake_child_exit - waitpid failed, "
"errno = %d\n", errno); "errno = %d\n", errno);
......
...@@ -192,7 +192,7 @@ int tracer(int (*init_proc)(void *), void *sp) ...@@ -192,7 +192,7 @@ int tracer(int (*init_proc)(void *), void *sp)
printf("tracing thread pid = %d\n", tracing_pid); printf("tracing thread pid = %d\n", tracing_pid);
pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
n = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0){ if(n < 0){
printf("waitpid on idle thread failed, errno = %d\n", errno); printf("waitpid on idle thread failed, errno = %d\n", errno);
exit(1); exit(1);
...@@ -233,7 +233,7 @@ int tracer(int (*init_proc)(void *), void *sp) ...@@ -233,7 +233,7 @@ int tracer(int (*init_proc)(void *), void *sp)
} }
set_cmdline("(tracing thread)"); set_cmdline("(tracing thread)");
while(1){ while(1){
pid = waitpid(-1, &status, WUNTRACED); CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
if(pid <= 0){ if(pid <= 0){
if(errno != ECHILD){ if(errno != ECHILD){
printf("wait failed - errno = %d\n", errno); printf("wait failed - errno = %d\n", errno);
......
...@@ -80,11 +80,10 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay) ...@@ -80,11 +80,10 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
int status, ret; int status, ret;
while(1){ while(1){
ret = waitpid(pid, &status, WUNTRACED); CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
if((ret < 0) || if((ret < 0) ||
!WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
if(ret < 0){ if(ret < 0){
if(errno == EINTR) continue;
printk("wait failed, errno = %d\n", printk("wait failed, errno = %d\n",
errno); errno);
} }
...@@ -124,8 +123,7 @@ int __raw(int fd, int complain, int now) ...@@ -124,8 +123,7 @@ int __raw(int fd, int complain, int now)
int err; int err;
int when; int when;
while (((err = tcgetattr(fd, &tt)) < 0) && errno == EINTR) CATCH_EINTR(err = tcgetattr(fd, &tt));
;
if (err < 0) { if (err < 0) {
if (complain) if (complain)
...@@ -140,8 +138,8 @@ int __raw(int fd, int complain, int now) ...@@ -140,8 +138,8 @@ int __raw(int fd, int complain, int now)
else else
when = TCSADRAIN; when = TCSADRAIN;
while (((err = tcsetattr(fd, when, &tt)) < 0) && errno == EINTR) CATCH_EINTR(err = tcsetattr(fd, when, &tt));
;
if (err < 0) { if (err < 0) {
if (complain) if (complain)
printk("tcsetattr failed, errno = %d\n", errno); printk("tcsetattr failed, errno = %d\n", errno);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <net/if.h> #include <net/if.h>
#include "user.h" #include "user.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h"
#include "net_user.h" #include "net_user.h"
#include "etap.h" #include "etap.h"
#include "helper.h" #include "helper.h"
...@@ -125,7 +126,8 @@ static int etap_tramp(char *dev, char *gate, int control_me, ...@@ -125,7 +126,8 @@ static int etap_tramp(char *dev, char *gate, int control_me,
if(c != 1){ if(c != 1){
printk("etap_tramp : uml_net failed\n"); printk("etap_tramp : uml_net failed\n");
err = -EINVAL; err = -EINVAL;
if(waitpid(pid, &status, 0) < 0) CATCH_EINTR(n = waitpid(pid, &status, 0));
if(n < 0)
err = -errno; err = -errno;
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
printk("uml_net didn't exit with status 1\n"); printk("uml_net didn't exit with status 1\n");
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "net_user.h" #include "net_user.h"
#include "tuntap.h" #include "tuntap.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h"
#include "user.h" #include "user.h"
#include "helper.h" #include "helper.h"
#include "os.h" #include "os.h"
...@@ -108,7 +109,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, ...@@ -108,7 +109,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
errno); errno);
return(-errno); return(-errno);
} }
waitpid(pid, NULL, 0); CATCH_EINTR(waitpid(pid, NULL, 0));
cmsg = CMSG_FIRSTHDR(&msg); cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){ if(cmsg == NULL){
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include "os.h" #include "os.h"
#include "user.h" #include "user.h"
#include "user_util.h"
#define ARBITRARY_ADDR -1 #define ARBITRARY_ADDR -1
#define FAILURE_PID -1 #define FAILURE_PID -1
...@@ -87,7 +88,7 @@ void os_kill_process(int pid, int reap_child) ...@@ -87,7 +88,7 @@ void os_kill_process(int pid, int reap_child)
{ {
kill(pid, SIGKILL); kill(pid, SIGKILL);
if(reap_child) if(reap_child)
waitpid(pid, NULL, 0); CATCH_EINTR(waitpid(pid, NULL, 0));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment