From: 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: Signed-off-by: Andrew Morton --- 25-akpm/arch/um/drivers/net_user.c | 3 ++- 25-akpm/arch/um/drivers/slip_user.c | 6 ++++-- 25-akpm/arch/um/drivers/slirp_user.c | 8 ++++---- 25-akpm/arch/um/include/user_util.h | 1 + 25-akpm/arch/um/kernel/frame.c | 8 +++++--- 25-akpm/arch/um/kernel/helper.c | 3 ++- 25-akpm/arch/um/kernel/process.c | 11 ++++++----- 25-akpm/arch/um/kernel/skas/exec_user.c | 6 ++++-- 25-akpm/arch/um/kernel/skas/process.c | 6 +++--- 25-akpm/arch/um/kernel/trap_user.c | 9 ++++++++- 25-akpm/arch/um/kernel/tt/exec_user.c | 9 +++++++-- 25-akpm/arch/um/kernel/tt/ptproxy/proxy.c | 4 ++-- 25-akpm/arch/um/kernel/tt/tracer.c | 4 ++-- 25-akpm/arch/um/kernel/user_util.c | 10 ++++------ 25-akpm/arch/um/os-Linux/drivers/ethertap_user.c | 4 +++- 25-akpm/arch/um/os-Linux/drivers/tuntap_user.c | 3 ++- 25-akpm/arch/um/os-Linux/process.c | 3 ++- 17 files changed, 61 insertions(+), 37 deletions(-) diff -puN arch/um/drivers/net_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/drivers/net_user.c --- 25/arch/um/drivers/net_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.197845288 -0700 +++ 25-akpm/arch/um/drivers/net_user.c 2004-07-05 16:00:47.223841336 -0700 @@ -175,7 +175,8 @@ static int change_tramp(char **argv, cha os_close_file(fds[1]); read_output(fds[0], output, output_len); - waitpid(pid, NULL, 0); + + CATCH_EINTR(err = waitpid(pid, NULL, 0)); return(pid); } diff -puN arch/um/drivers/slip_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/drivers/slip_user.c --- 25/arch/um/drivers/slip_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.198845136 -0700 +++ 25-akpm/arch/um/drivers/slip_user.c 2004-07-05 16:00:47.223841336 -0700 @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -100,7 +100,9 @@ static int slip_tramp(char **argv, int f printk("%s", 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)){ printk("'%s' didn't exit with status 0\n", argv[0]); err = -EINVAL; diff -puN arch/um/drivers/slirp_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/drivers/slirp_user.c --- 25/arch/um/drivers/slirp_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.200844832 -0700 +++ 25-akpm/arch/um/drivers/slirp_user.c 2004-07-05 16:00:47.224841184 -0700 @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include "user_util.h" @@ -113,13 +113,13 @@ static void slirp_close(int fd, void *da } #endif - err = waitpid(pri->pid, &status, WNOHANG); - if(err<0) { + CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); + if(err < 0) { printk("slirp_close: waitpid returned %d\n", errno); return; } - if(err==0) { + if(err == 0) { printk("slirp_close: process %d has not exited\n"); return; } diff -puN arch/um/include/user_util.h~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/include/user_util.h --- 25/arch/um/include/user_util.h~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.201844680 -0700 +++ 25-akpm/arch/um/include/user_util.h 2004-07-05 16:00:47.224841184 -0700 @@ -92,6 +92,7 @@ extern void arch_init_thread(void); extern int __raw(int fd, int complain, int now); #define raw(fd, complain) __raw((fd), (complain), 1) +#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR) #endif /* diff -puN arch/um/kernel/frame.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/frame.c --- 25/arch/um/kernel/frame.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.203844376 -0700 +++ 25-akpm/arch/um/kernel/frame.c 2004-07-05 16:00:47.225841032 -0700 @@ -21,6 +21,7 @@ #include "sysdep/sigcontext.h" #include "frame_user.h" #include "kern_util.h" +#include "user_util.h" #include "ptrace_user.h" #include "os.h" @@ -40,7 +41,7 @@ static int capture_stack(int (*child)(vo /* Wait for it to stop itself and continue it with a SIGUSR1 to force * it into the signal handler. */ - n = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0){ printf("capture_stack : waitpid failed - errno = %d\n", errno); exit(1); @@ -60,7 +61,7 @@ static int capture_stack(int (*child)(vo * At this point, the handler has stuffed the addresses of * sig, sc, and SA_RESTORER in raw. */ - n = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0){ printf("capture_stack : waitpid failed - errno = %d\n", errno); exit(1); @@ -82,7 +83,8 @@ static int capture_stack(int (*child)(vo errno); 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); exit(1); } diff -puN arch/um/kernel/helper.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/helper.c --- 25/arch/um/kernel/helper.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.204844224 -0700 +++ 25-akpm/arch/um/kernel/helper.c 2004-07-05 16:00:47.225841032 -0700 @@ -12,6 +12,7 @@ #include #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "os.h" struct helper_data { @@ -96,7 +97,7 @@ int run_helper(void (*pre_exec)(void *), goto out_kill; } else if(n != 0){ - waitpid(pid, NULL, 0); + CATCH_EINTR(n = waitpid(pid, NULL, 0)); pid = -errno; } diff -puN arch/um/kernel/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/process.c --- 25/arch/um/kernel/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.206843920 -0700 +++ 25-akpm/arch/um/kernel/process.c 2004-07-05 16:00:47.226840880 -0700 @@ -125,7 +125,7 @@ int start_fork_tramp(void *thread_arg, u /* Start the process and wait for it to kill itself */ new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); 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", errno); if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) @@ -171,7 +171,7 @@ static int start_ptraced_child(void **st pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); if(pid < 0) panic("check_ptrace : clone failed, errno = %d", errno); - n = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) @@ -188,7 +188,7 @@ static void stop_ptraced_child(int pid, if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 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)) panic("check_ptrace : child exited with status 0x%x", status); @@ -226,7 +226,8 @@ static void __init check_sysemu(void) if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { 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); if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) panic("check_ptrace : expected SIGTRAP, " @@ -267,7 +268,7 @@ void __init check_ptrace(void) if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) panic("check_ptrace : ptrace failed, errno = %d", errno); - n = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) diff -puN arch/um/kernel/skas/exec_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/skas/exec_user.c --- 25/arch/um/kernel/skas/exec_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.207843768 -0700 +++ 25-akpm/arch/um/kernel/skas/exec_user.c 2004-07-05 16:00:47.227840728 -0700 @@ -11,6 +11,7 @@ #include #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "os.h" #include "time_user.h" @@ -26,7 +27,7 @@ static int user_thread_tramp(void *arg) int user_thread(unsigned long stack, int flags) { - int pid, status; + int pid, status, err; pid = clone(user_thread_tramp, (void *) stack_sp(stack), flags | CLONE_FILES | SIGCHLD, NULL); @@ -35,7 +36,8 @@ int user_thread(unsigned long stack, int 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); return(-errno); } diff -puN arch/um/kernel/skas/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/skas/process.c --- 25/arch/um/kernel/skas/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.209843464 -0700 +++ 25-akpm/arch/um/kernel/skas/process.c 2004-07-05 16:00:47.227840728 -0700 @@ -81,7 +81,7 @@ static void handle_trap(int pid, union u panic("handle_trap - continuing to end of syscall failed, " "errno = %d\n", errno); - err = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); @@ -121,7 +121,7 @@ void start_userspace(int cpu) panic("start_userspace : clone failed, errno = %d", errno); do { - n = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("start_userspace : wait failed, errno = %d", errno); @@ -154,7 +154,7 @@ void userspace(union uml_pt_regs *regs) panic("userspace - PTRACE_%s failed, errno = %d\n", local_using_sysemu ? "SYSEMU" : "SYSCALL", errno); while(1){ - err = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if(err < 0) panic("userspace - waitpid failed, errno = %d\n", errno); diff -puN arch/um/kernel/trap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/trap_user.c --- 25/arch/um/kernel/trap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.210843312 -0700 +++ 25-akpm/arch/um/kernel/trap_user.c 2004-07-05 16:00:47.228840576 -0700 @@ -32,7 +32,14 @@ void kill_child_dead(int pid) { kill(pid, SIGKILL); 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 */ diff -puN arch/um/kernel/tt/exec_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/tt/exec_user.c --- 25/arch/um/kernel/tt/exec_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.211843160 -0700 +++ 25-akpm/arch/um/kernel/tt/exec_user.c 2004-07-05 16:00:47.228840576 -0700 @@ -19,13 +19,18 @@ void do_exec(int old_pid, int new_pid) { unsigned long regs[FRAME_SIZE]; + int err; if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) || - (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) || - (waitpid(new_pid, 0, WUNTRACED) < 0)) + (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0)) tracer_panic("do_exec failed to attach proc - errno = %d", 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) tracer_panic("do_exec failed to get registers - errno = %d", errno); diff -puN arch/um/kernel/tt/ptproxy/proxy.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/tt/ptproxy/proxy.c --- 25/arch/um/kernel/tt/ptproxy/proxy.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.213842856 -0700 +++ 25-akpm/arch/um/kernel/tt/ptproxy/proxy.c 2004-07-05 16:00:47.229840424 -0700 @@ -272,7 +272,7 @@ void fake_child_exit(void) child_proxy(1, W_EXITCODE(0, 0)); while(debugger.waiting == 1){ - pid = waitpid(debugger.pid, &status, WUNTRACED); + CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); if(pid != debugger.pid){ printk("fake_child_exit - waitpid failed, " "errno = %d\n", errno); @@ -280,7 +280,7 @@ void fake_child_exit(void) } debugger_proxy(status, debugger.pid); } - pid = waitpid(debugger.pid, &status, WUNTRACED); + CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED)); if(pid != debugger.pid){ printk("fake_child_exit - waitpid failed, " "errno = %d\n", errno); diff -puN arch/um/kernel/tt/tracer.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/tt/tracer.c --- 25/arch/um/kernel/tt/tracer.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.214842704 -0700 +++ 25-akpm/arch/um/kernel/tt/tracer.c 2004-07-05 16:00:47.230840272 -0700 @@ -192,7 +192,7 @@ int tracer(int (*init_proc)(void *), voi printf("tracing thread pid = %d\n", tracing_pid); 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){ printf("waitpid on idle thread failed, errno = %d\n", errno); exit(1); @@ -233,7 +233,7 @@ int tracer(int (*init_proc)(void *), voi } set_cmdline("(tracing thread)"); while(1){ - pid = waitpid(-1, &status, WUNTRACED); + CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED)); if(pid <= 0){ if(errno != ECHILD){ printf("wait failed - errno = %d\n", errno); diff -puN arch/um/kernel/user_util.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/kernel/user_util.c --- 25/arch/um/kernel/user_util.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.215842552 -0700 +++ 25-akpm/arch/um/kernel/user_util.c 2004-07-05 16:00:47.230840272 -0700 @@ -80,11 +80,10 @@ int wait_for_stop(int pid, int sig, int int status, ret; while(1){ - ret = waitpid(pid, &status, WUNTRACED); + CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED)); if((ret < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ if(ret < 0){ - if(errno == EINTR) continue; printk("wait failed, errno = %d\n", errno); } @@ -124,8 +123,7 @@ int __raw(int fd, int complain, int now) int err; int when; - while (((err = tcgetattr(fd, &tt)) < 0) && errno == EINTR) - ; + CATCH_EINTR(err = tcgetattr(fd, &tt)); if (err < 0) { if (complain) @@ -140,8 +138,8 @@ int __raw(int fd, int complain, int now) else when = TCSADRAIN; - while (((err = tcsetattr(fd, when, &tt)) < 0) && errno == EINTR) - ; + CATCH_EINTR(err = tcsetattr(fd, when, &tt)); + if (err < 0) { if (complain) printk("tcsetattr failed, errno = %d\n", errno); diff -puN arch/um/os-Linux/drivers/ethertap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/os-Linux/drivers/ethertap_user.c --- 25/arch/um/os-Linux/drivers/ethertap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.217842248 -0700 +++ 25-akpm/arch/um/os-Linux/drivers/ethertap_user.c 2004-07-05 16:00:47.231840120 -0700 @@ -16,6 +16,7 @@ #include #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "net_user.h" #include "etap.h" #include "helper.h" @@ -125,7 +126,8 @@ static int etap_tramp(char *dev, char *g if(c != 1){ printk("etap_tramp : uml_net failed\n"); err = -EINVAL; - if(waitpid(pid, &status, 0) < 0) + CATCH_EINTR(n = waitpid(pid, &status, 0)); + if(n < 0) err = -errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) printk("uml_net didn't exit with status 1\n"); diff -puN arch/um/os-Linux/drivers/tuntap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/os-Linux/drivers/tuntap_user.c --- 25/arch/um/os-Linux/drivers/tuntap_user.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.218842096 -0700 +++ 25-akpm/arch/um/os-Linux/drivers/tuntap_user.c 2004-07-05 16:00:47.231840120 -0700 @@ -18,6 +18,7 @@ #include "net_user.h" #include "tuntap.h" #include "kern_util.h" +#include "user_util.h" #include "user.h" #include "helper.h" #include "os.h" @@ -108,7 +109,7 @@ static int tuntap_open_tramp(char *gate, errno); return(-errno); } - waitpid(pid, NULL, 0); + CATCH_EINTR(waitpid(pid, NULL, 0)); cmsg = CMSG_FIRSTHDR(&msg); if(cmsg == NULL){ diff -puN arch/um/os-Linux/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places arch/um/os-Linux/process.c --- 25/arch/um/os-Linux/process.c~uml-handles-correctly-errno-==-eintr-in-lots-of-places 2004-07-05 16:00:47.219841944 -0700 +++ 25-akpm/arch/um/os-Linux/process.c 2004-07-05 16:00:47.232839968 -0700 @@ -12,6 +12,7 @@ #include #include "os.h" #include "user.h" +#include "user_util.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -87,7 +88,7 @@ void os_kill_process(int pid, int reap_c { kill(pid, SIGKILL); if(reap_child) - waitpid(pid, NULL, 0); + CATCH_EINTR(waitpid(pid, NULL, 0)); } _