From d8872c43b48eae5501998a4e5a84337017d8fbe6 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sat, 31 May 2014 12:33:24 -0500 Subject: Introduce xfork() and make commands use it, and make some WEXITSTATUS() use WIFEXITED() and WTERMSIG()+127. --- lib/lib.h | 1 + lib/xwrap.c | 9 +++++++++ toys/other/netcat.c | 4 ++-- toys/other/timeout.c | 7 +++---- toys/pending/bootchartd.c | 4 ++-- toys/pending/dhcp.c | 4 +--- toys/pending/find.c | 2 +- toys/pending/inotifyd.c | 5 ++--- toys/pending/nbd_client.c | 2 +- toys/pending/openvt.c | 5 ++--- toys/pending/tcpsvd.c | 8 ++++---- toys/pending/useradd.c | 8 ++++---- toys/posix/time.c | 2 +- toys/posix/xargs.c | 4 ++-- 14 files changed, 35 insertions(+), 30 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 09af2837..3ca631b6 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -91,6 +91,7 @@ void xprintf(char *format, ...); void xputs(char *s); void xputc(char c); void xflush(void); +pid_t xfork(void); void xexec_optargs(int skip); void xexec(char **argv); void xaccess(char *path, int flags); diff --git a/lib/xwrap.c b/lib/xwrap.c index 69682f65..3e146fb7 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -113,6 +113,15 @@ void xflush(void) if (fflush(stdout) || ferror(stdout)) perror_exit("write");; } +pid_t xfork(void) +{ + pid_t pid = fork(); + + if (pid < 0) perror_exit("fork"); + + return pid; +} + // Call xexec with a chunk of optargs, starting at skip. (You can't just // call xexec() directly because toy_init() frees optargs.) void xexec_optargs(int skip) diff --git a/toys/other/netcat.c b/toys/other/netcat.c index d002b047..3c6f630b 100644 --- a/toys/other/netcat.c +++ b/toys/other/netcat.c @@ -140,7 +140,7 @@ void netcat_main(void) // Do we need to return immediately because -l has arguments? if ((toys.optflags & FLAG_l) && toys.optc) { - if (fork()) goto cleanup; + if (xfork()) goto cleanup; close(0); close(1); close(2); @@ -149,7 +149,7 @@ void netcat_main(void) for (;;) { pid_t child = 0; - // For -l, call accept from the _new_ thread. + // For -l, call accept from the _new_ process. pollfds[0].fd = accept(sockfd, (struct sockaddr *)&address, &len); if (pollfds[0].fd<0) perror_exit("accept"); diff --git a/toys/other/timeout.c b/toys/other/timeout.c index 4b8a87df..f8acabf5 100644 --- a/toys/other/timeout.c +++ b/toys/other/timeout.c @@ -60,15 +60,14 @@ void timeout_main(void) if (TT.s_signal && -1 == (TT.nextsig = sig_to_num(TT.s_signal))) error_exit("bad -s: '%s'", TT.s_signal); - if (!(TT.pid = fork())) xexec_optargs(1); + if (!(TT.pid = xfork())) xexec_optargs(1); else { int status; signal(SIGALRM, handler); setitimer(ITIMER_REAL, &TT.itv, (void *)&toybuf); while (-1 == waitpid(TT.pid, &status, 0) && errno == EINTR); - if (WIFEXITED(status)) toys.exitval = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) toys.exitval = WTERMSIG(status); - else toys.exitval = 1; + toys.exitval = WIFEXITED(status) + ? WEXITSTATUS(status) : WTERMSIG(status) + 127; } } diff --git a/toys/pending/bootchartd.c b/toys/pending/bootchartd.c index 6839b2ca..cbed4ac0 100644 --- a/toys/pending/bootchartd.c +++ b/toys/pending/bootchartd.c @@ -281,7 +281,7 @@ void bootchartd_main() parse_config_file("/etc/bootchartd.conf"); memset(toybuf, 0, sizeof(toybuf)); - if (!(lgr_pid = fork())) { + if (!(lgr_pid = xfork())) { char *tmp_dir = create_tmp_dir(); sigatexit(generic_signal); @@ -306,7 +306,7 @@ void bootchartd_main() if (bchartd_opt == 1 && toys.optargs[1]) { pid_t prog_pid; - if (!(prog_pid = fork())) xexec_optargs(1); + if (!(prog_pid = xfork())) xexec_optargs(1); waitpid(prog_pid, NULL, 0); kill(lgr_pid, SIGUSR1); } diff --git a/toys/pending/dhcp.c b/toys/pending/dhcp.c index 2b432cb3..636746da 100644 --- a/toys/pending/dhcp.c +++ b/toys/pending/dhcp.c @@ -318,10 +318,8 @@ static int dhcp_daemon(void) { int fd = open("/dev/null", O_RDWR); if (fd < 0) fd = xcreate("/", O_RDONLY, 0666); - pid_t pid = fork(); - if (pid < 0) perror_exit("DAEMON: failed to fork"); - if (pid) exit(EXIT_SUCCESS); + if (xfork()) exit(0); setsid(); dup2(fd, 0); diff --git a/toys/pending/find.c b/toys/pending/find.c index 58e554b8..1600f5f8 100644 --- a/toys/pending/find.c +++ b/toys/pending/find.c @@ -94,7 +94,7 @@ static int do_exec(struct filter_node *filter, struct dirtree *node) arg_array[filter->data.e.arg_path_index] = path; } - if (!(pid = fork())) xexec(arg_array); + if (!(pid = xfork())) xexec(arg_array); free(path); waitpid(pid, &status, 0); diff --git a/toys/pending/inotifyd.c b/toys/pending/inotifyd.c index 98de2546..657fcb5f 100644 --- a/toys/pending/inotifyd.c +++ b/toys/pending/inotifyd.c @@ -55,11 +55,10 @@ static void sig_handler(int sig) static int exec_wait(char **args) { int status = 0; - pid_t pid = fork(); + pid_t pid = xfork(); if (!pid) xexec(args); - else if (pid > 0) waitpid(pid, &status, 0); - else perror_exit("fork"); + else waitpid(pid, &status, 0); return WEXITSTATUS(status); } diff --git a/toys/pending/nbd_client.c b/toys/pending/nbd_client.c index 9164a114..9a5b2f74 100644 --- a/toys/pending/nbd_client.c +++ b/toys/pending/nbd_client.c @@ -100,7 +100,7 @@ void nbd_client_main(void) if (toys.optflags & FLAG_s) mlockall(MCL_CURRENT|MCL_FUTURE); // Open the device to force reread of the partition table. - if ((toys.optflags & FLAG_n) || !fork()) { + if ((toys.optflags & FLAG_n) || !xfork()) { char *s = strrchr(device, '/'); int i; diff --git a/toys/pending/openvt.c b/toys/pending/openvt.c index f136b1b7..be3070e2 100644 --- a/toys/pending/openvt.c +++ b/toys/pending/openvt.c @@ -110,9 +110,8 @@ void openvt_main(void) while (vt_fd > 2) close(vt_fd--); - pid = vfork(); - if (pid < 0) perror_exit("Fork failed"); - else if (!pid) { + pid = xfork(); + if (!pid) { setsid(); ioctl(vt_fd, TIOCSCTTY, 0); xexec(toys.optargs); diff --git a/toys/pending/tcpsvd.c b/toys/pending/tcpsvd.c index 031d7238..d7e1f6c1 100644 --- a/toys/pending/tcpsvd.c +++ b/toys/pending/tcpsvd.c @@ -14,7 +14,7 @@ config TCPSVD default n help usage: tcpsvd [-hEv] [-c N] [-C N[:MSG]] [-b N] [-u User] [-l Name] IP Port Prog - udpsvd [-hEv] [-c N] [-u User] [-l Name] IP Port Prog + usage: udpsvd [-hEv] [-c N] [-u User] [-l Name] IP Port Prog Create TCP/UDP socket, bind to IP:PORT and listen for incoming connection. Run PROG for each connection. @@ -350,7 +350,7 @@ void tcpsvd_main(void) h[hash].head->count++; } - if (!(pid = fork())) { + if (!(pid = xfork())) { char *serv = NULL, *clie = NULL; char *client = sock_to_address((struct sockaddr*)buf, NI_NUMERICHOST | NI_NUMERICSERV); if (toys.optflags & FLAG_h) { //lookup name @@ -393,11 +393,11 @@ void tcpsvd_main(void) dup2(newfd, 0); dup2(newfd, 1); xexec_optargs(2); //skip IP PORT - } else if(pid > 0) { + } else { insert(&pids, pid, addr); xclose(newfd); //close and reopen for next client. if (TT.udp) fd = create_bind_sock(toys.optargs[0], (struct sockaddr*)&haddr); - } else error_msg(" fork failed"); + } } //while(1) } diff --git a/toys/pending/useradd.c b/toys/pending/useradd.c index 450e021a..99e2530f 100644 --- a/toys/pending/useradd.c +++ b/toys/pending/useradd.c @@ -58,12 +58,12 @@ static char* get_shell(void) static int exec_wait(char **args) { int status = 0; - pid_t pid = fork(); + pid_t pid = xfork(); if (!pid) xexec(args); - else if (pid > 0) waitpid(pid, &status, 0); - else perror_exit("fork failed"); - return WEXITSTATUS(status); + else if waitpid(pid, &status, 0); + + return WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127; } /* create_copy_skel(), This function will create the home directory of the diff --git a/toys/posix/time.c b/toys/posix/time.c index 2648cd1c..01592052 100644 --- a/toys/posix/time.c +++ b/toys/posix/time.c @@ -27,7 +27,7 @@ void time_main(void) struct timeval tv, tv2; gettimeofday(&tv, NULL); - if (!(pid = fork())) xexec_optargs(0); + if (!(pid = xfork())) xexec_optargs(0); else { int stat; struct rusage ru; diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c index b024789f..cde71f61 100644 --- a/toys/posix/xargs.c +++ b/toys/posix/xargs.c @@ -166,14 +166,14 @@ void xargs_main(void) for (dtemp = dlist; dtemp; dtemp = dtemp->next) handle_entries(dtemp->data, out+entries); - pid_t pid=fork(); + pid_t pid=xfork(); if (!pid) { xclose(0); open("/dev/null", O_RDONLY); xexec(out); } waitpid(pid, &status, 0); - status = WEXITSTATUS(status); + status = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127; // Abritrary number of execs, can't just leak memory each time... while (dlist) { -- cgit v1.2.3