libbb: introduce and use safe_waitpid (loops in EINTR)
*: use more approproate (shorter) versions of wait() function old new delta safe_waitpid - 48 +48 wait_any_nohang - 17 +17 send_tree 365 369 +4 processorstop 432 435 +3 text_yank 110 108 -2 make_human_readable_str 202 200 -2 crond_main 1368 1366 -2 handle_sigchld 49 43 -6 reapchild 166 159 -7 custom 260 250 -10 checkscript 191 177 -14 wait_nohang 17 - -17 wait_pid 43 - -43 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 2/7 up/down: 72/-103) Total: -31 bytes
This commit is contained in:
parent
27963980db
commit
fb0eba706c
@ -610,7 +610,7 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
|
|||||||
|
|
||||||
if (gzipPid) {
|
if (gzipPid) {
|
||||||
int status;
|
int status;
|
||||||
if (waitpid(gzipPid, &status, 0) == -1)
|
if (safe_waitpid(gzipPid, &status, 0) == -1)
|
||||||
bb_perror_msg("waitpid");
|
bb_perror_msg("waitpid");
|
||||||
else if (!WIFEXITED(status) || WEXITSTATUS(status))
|
else if (!WIFEXITED(status) || WEXITSTATUS(status))
|
||||||
/* gzip was killed or has exited with nonzero! */
|
/* gzip was killed or has exited with nonzero! */
|
||||||
@ -688,7 +688,7 @@ static void handle_SIGCHLD(int status)
|
|||||||
/* Actually, 'status' is a signo. We reuse it for other needs */
|
/* Actually, 'status' is a signo. We reuse it for other needs */
|
||||||
|
|
||||||
/* Wait for any child without blocking */
|
/* Wait for any child without blocking */
|
||||||
if (waitpid(-1, &status, WNOHANG) < 0)
|
if (wait_any_nohang(&status) < 0)
|
||||||
/* wait failed?! I'm confused... */
|
/* wait failed?! I'm confused... */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -587,9 +587,9 @@ pid_t xspawn(char **argv);
|
|||||||
* if (rc < 0) bb_perror_msg("%s", argv[0]);
|
* if (rc < 0) bb_perror_msg("%s", argv[0]);
|
||||||
* if (rc > 0) bb_error_msg("exit code: %d", rc);
|
* if (rc > 0) bb_error_msg("exit code: %d", rc);
|
||||||
*/
|
*/
|
||||||
|
int safe_waitpid(int pid, int *wstat, int options);
|
||||||
int wait4pid(int pid);
|
int wait4pid(int pid);
|
||||||
int wait_pid(int *wstat, int pid);
|
int wait_any_nohang(int *wstat);
|
||||||
int wait_nohang(int *wstat);
|
|
||||||
#define wait_crashed(w) ((w) & 127)
|
#define wait_crashed(w) ((w) & 127)
|
||||||
#define wait_exitcode(w) ((w) >> 8)
|
#define wait_exitcode(w) ((w) >> 8)
|
||||||
#define wait_stopsig(w) ((w) >> 8)
|
#define wait_stopsig(w) ((w) >> 8)
|
||||||
|
26
init/init.c
26
init/init.c
@ -95,9 +95,14 @@ static const char *const environment[] = {
|
|||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
static void delete_init_action(struct init_action *a);
|
static void delete_init_action(struct init_action *a);
|
||||||
static int waitfor(pid_t pid);
|
|
||||||
static void halt_reboot_pwoff(int sig) ATTRIBUTE_NORETURN;
|
static void halt_reboot_pwoff(int sig) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
|
/* TODO: move to libbb? */
|
||||||
|
static int waitfor(pid_t runpid)
|
||||||
|
{
|
||||||
|
return safe_waitpid(runpid, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void loop_forever(void) ATTRIBUTE_NORETURN;
|
static void loop_forever(void) ATTRIBUTE_NORETURN;
|
||||||
static void loop_forever(void)
|
static void loop_forever(void)
|
||||||
{
|
{
|
||||||
@ -465,19 +470,6 @@ static pid_t run(const struct init_action *a)
|
|||||||
_exit(-1);
|
_exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int waitfor(pid_t runpid)
|
|
||||||
{
|
|
||||||
int status, wpid;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
wpid = waitpid(runpid, &status, 0);
|
|
||||||
if (wpid == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return wpid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run all commands of a particular type */
|
/* Run all commands of a particular type */
|
||||||
static void run_actions(int action)
|
static void run_actions(int action)
|
||||||
{
|
{
|
||||||
@ -520,7 +512,7 @@ static void init_reboot(unsigned long magic)
|
|||||||
reboot(magic);
|
reboot(magic);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
waitpid(pid, NULL, 0);
|
waitfor(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kill_all_processes(void)
|
static void kill_all_processes(void)
|
||||||
@ -980,7 +972,7 @@ int init_main(int argc, char **argv)
|
|||||||
/* Don't consume all CPU time -- sleep a bit */
|
/* Don't consume all CPU time -- sleep a bit */
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
/* Wait for a child process to exit */
|
/* Wait for any child process to exit */
|
||||||
wpid = wait(NULL);
|
wpid = wait(NULL);
|
||||||
while (wpid > 0) {
|
while (wpid > 0) {
|
||||||
/* Find out who died and clean up their corpse */
|
/* Find out who died and clean up their corpse */
|
||||||
@ -995,7 +987,7 @@ int init_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* see if anyone else is waiting to be reaped */
|
/* see if anyone else is waiting to be reaped */
|
||||||
wpid = waitpid(-1, NULL, WNOHANG);
|
wpid = wait_any_nohang(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ static void sig_child_handler(int sig)
|
|||||||
int wstat;
|
int wstat;
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
while ((pid = wait_nohang(&wstat)) > 0) {
|
while ((pid = wait_any_nohang(&wstat)) > 0) {
|
||||||
if (max_per_host)
|
if (max_per_host)
|
||||||
ipsvd_perhost_remove(pid);
|
ipsvd_perhost_remove(pid);
|
||||||
if (cnum)
|
if (cnum)
|
||||||
|
@ -66,6 +66,21 @@ pid_t xspawn(char **argv)
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int safe_waitpid(int pid, int *wstat, int options)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
do
|
||||||
|
r = waitpid(pid, wstat, options);
|
||||||
|
while ((r == -1) && (errno == EINTR));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wait_any_nohang(int *wstat)
|
||||||
|
{
|
||||||
|
return safe_waitpid(-1, wstat, WNOHANG);
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the specified child PID to exit, returning child's error return.
|
// Wait for the specified child PID to exit, returning child's error return.
|
||||||
int wait4pid(int pid)
|
int wait4pid(int pid)
|
||||||
{
|
{
|
||||||
@ -76,28 +91,18 @@ int wait4pid(int pid)
|
|||||||
/* we expect errno to be already set from failed [v]fork/exec */
|
/* we expect errno to be already set from failed [v]fork/exec */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (waitpid(pid, &status, 0) == -1)
|
if (safe_waitpid(pid, &status, 0) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
if (WIFSIGNALED(status))
|
if (WIFSIGNALED(status))
|
||||||
return WTERMSIG(status) + 1000;
|
return WTERMSIG(status) + 1000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if (WIFEXITED(status))
|
||||||
|
return WEXITSTATUS(status);
|
||||||
int wait_nohang(int *wstat)
|
if (WIFSIGNALED(status))
|
||||||
{
|
return WTERMSIG(status) + 1000;
|
||||||
return waitpid(-1, wstat, WNOHANG);
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
int wait_pid(int *wstat, int pid)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
do
|
|
||||||
r = waitpid(pid, wstat, 0);
|
|
||||||
while ((r == -1) && (errno == EINTR));
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_PREFER_APPLETS
|
#if ENABLE_FEATURE_PREFER_APPLETS
|
||||||
|
@ -756,7 +756,7 @@ static int CheckJobs(void)
|
|||||||
for (line = file->cf_LineBase; line; line = line->cl_Next) {
|
for (line = file->cf_LineBase; line; line = line->cl_Next) {
|
||||||
if (line->cl_Pid > 0) {
|
if (line->cl_Pid > 0) {
|
||||||
int status;
|
int status;
|
||||||
int r = wait4(line->cl_Pid, &status, WNOHANG, NULL);
|
int r = waitpid(line->cl_Pid, &status, WNOHANG);
|
||||||
|
|
||||||
if (r < 0 || r == line->cl_Pid) {
|
if (r < 0 || r == line->cl_Pid) {
|
||||||
EndJob(file->cf_User, line);
|
EndJob(file->cf_User, line);
|
||||||
|
@ -1152,7 +1152,7 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post
|
|||||||
count = safe_poll(pfd, 3, -1);
|
count = safe_poll(pfd, 3, -1);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
#if 0
|
#if 0
|
||||||
if (waitpid(pid, &status, WNOHANG) <= 0) {
|
if (safe_waitpid(pid, &status, WNOHANG) <= 0) {
|
||||||
/* Weird. CGI didn't exit and no fd's
|
/* Weird. CGI didn't exit and no fd's
|
||||||
* are ready, yet poll returned?! */
|
* are ready, yet poll returned?! */
|
||||||
continue;
|
continue;
|
||||||
|
@ -944,7 +944,7 @@ static int doit(char *str)
|
|||||||
execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, my_environ);
|
execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, my_environ);
|
||||||
exit(127);
|
exit(127);
|
||||||
}
|
}
|
||||||
waitpid(child, &status, 0);
|
safe_waitpid(child, &status, 0);
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1068,7 +1068,7 @@ static char *run_mapping(char *physical, struct mapping_defn_t * map)
|
|||||||
fprintf(in, "%s\n", map->mapping[i]);
|
fprintf(in, "%s\n", map->mapping[i]);
|
||||||
}
|
}
|
||||||
fclose(in);
|
fclose(in);
|
||||||
waitpid(pid, &status, 0);
|
safe_waitpid(pid, &status, 0);
|
||||||
|
|
||||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||||
/* If the mapping script exited successfully, try to
|
/* If the mapping script exited successfully, try to
|
||||||
|
@ -1161,7 +1161,7 @@ static void reapchild(int sig ATTRIBUTE_UNUSED)
|
|||||||
servtab_t *sep;
|
servtab_t *sep;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = wait3(&status, WNOHANG, NULL);
|
pid = wait_any_nohang(&status);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
break;
|
break;
|
||||||
for (sep = servtab; sep; sep = sep->se_next)
|
for (sep = servtab; sep; sep = sep->se_next)
|
||||||
|
@ -394,7 +394,7 @@ static void handle_sigchld(int sig)
|
|||||||
|
|
||||||
/* Looping: more than one child may have exited */
|
/* Looping: more than one child may have exited */
|
||||||
while (1) {
|
while (1) {
|
||||||
pid = waitpid(-1, NULL, WNOHANG);
|
pid = wait_any_nohang(NULL);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
break;
|
break;
|
||||||
ts = sessions;
|
ts = sessions;
|
||||||
|
@ -232,7 +232,7 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name)
|
|||||||
name, NULL, envp);
|
name, NULL, envp);
|
||||||
bb_perror_msg_and_die("script %s failed", client_config.script);
|
bb_perror_msg_and_die("script %s failed", client_config.script);
|
||||||
}
|
}
|
||||||
waitpid(pid, NULL, 0);
|
safe_waitpid(pid, NULL, 0);
|
||||||
for (curr = envp; *curr; curr++)
|
for (curr = envp; *curr; curr++)
|
||||||
free(*curr);
|
free(*curr);
|
||||||
free(envp);
|
free(envp);
|
||||||
|
@ -282,8 +282,7 @@ static unsigned custom(struct svdir *s, char c)
|
|||||||
execve(a, prog, environ);
|
execve(a, prog, environ);
|
||||||
fatal_cannot("run control/?");
|
fatal_cannot("run control/?");
|
||||||
}
|
}
|
||||||
while (wait_pid(&w, pid) == -1) {
|
while (safe_waitpid(pid, &w, 0) == -1) {
|
||||||
if (errno == EINTR) continue;
|
|
||||||
warn_cannot("wait for child control/?");
|
warn_cannot("wait for child control/?");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -593,7 +592,7 @@ int runsv_main(int argc, char **argv)
|
|||||||
int child;
|
int child;
|
||||||
int wstat;
|
int wstat;
|
||||||
|
|
||||||
child = wait_nohang(&wstat);
|
child = wait_any_nohang(&wstat);
|
||||||
if (!child)
|
if (!child)
|
||||||
break;
|
break;
|
||||||
if ((child == -1) && (errno != EINTR))
|
if ((child == -1) && (errno != EINTR))
|
||||||
|
@ -252,7 +252,7 @@ int runsvdir_main(int argc, char **argv)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
/* collect children */
|
/* collect children */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = wait_nohang(&wstat);
|
pid = wait_any_nohang(&wstat);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
break;
|
break;
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
|
@ -333,8 +333,7 @@ static int checkscript(void)
|
|||||||
bb_perror_msg(WARN"cannot %s child %s/check", "run", *service);
|
bb_perror_msg(WARN"cannot %s child %s/check", "run", *service);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while (wait_pid(&w, pid) == -1) {
|
while (safe_waitpid(pid, &w, 0) == -1) {
|
||||||
if (errno == EINTR) continue;
|
|
||||||
bb_perror_msg(WARN"cannot %s child %s/check", "wait for", *service);
|
bb_perror_msg(WARN"cannot %s child %s/check", "wait for", *service);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ static unsigned processorstop(struct logdir *ld)
|
|||||||
|
|
||||||
if (ld->ppid) {
|
if (ld->ppid) {
|
||||||
sig_unblock(SIGHUP);
|
sig_unblock(SIGHUP);
|
||||||
while (wait_pid(&wstat, ld->ppid) == -1)
|
while (safe_waitpid(ld->ppid, &wstat, 0) == -1)
|
||||||
pause2cannot("wait for processor", ld->name);
|
pause2cannot("wait for processor", ld->name);
|
||||||
sig_block(SIGHUP);
|
sig_block(SIGHUP);
|
||||||
ld->ppid = 0;
|
ld->ppid = 0;
|
||||||
@ -794,7 +794,7 @@ static void sig_child_handler(int sig_no)
|
|||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
bb_error_msg(INFO"sig%s received", "child");
|
bb_error_msg(INFO"sig%s received", "child");
|
||||||
while ((pid = wait_nohang(&wstat)) > 0) {
|
while ((pid = wait_any_nohang(&wstat)) > 0) {
|
||||||
for (l = 0; l < dirn; ++l) {
|
for (l = 0; l < dirn; ++l) {
|
||||||
if (dir[l].ppid == pid) {
|
if (dir[l].ppid == pid) {
|
||||||
dir[l].ppid = 0;
|
dir[l].ppid = 0;
|
||||||
|
@ -3768,7 +3768,7 @@ waitproc(int block, int *status)
|
|||||||
#endif
|
#endif
|
||||||
if (block == 0)
|
if (block == 0)
|
||||||
flags |= WNOHANG;
|
flags |= WNOHANG;
|
||||||
return wait3(status, flags, (struct rusage *)NULL);
|
return waitpid(-1, status, flags); // safe_waitpid?
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1649,6 +1649,7 @@ static int checkjobs(struct pipe* fg_pipe)
|
|||||||
// + killall -STOP cat
|
// + killall -STOP cat
|
||||||
|
|
||||||
wait_more:
|
wait_more:
|
||||||
|
// TODO: safe_waitpid?
|
||||||
while ((childpid = waitpid(-1, &status, attributes)) > 0) {
|
while ((childpid = waitpid(-1, &status, attributes)) > 0) {
|
||||||
const int dead = WIFEXITED(status) || WIFSIGNALED(status);
|
const int dead = WIFEXITED(status) || WIFSIGNALED(status);
|
||||||
|
|
||||||
|
@ -4162,7 +4162,7 @@ static int grave(int quoted)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
waitpid(i, NULL, 0);
|
waitpid(i, NULL, 0); // safe_waitpid?
|
||||||
global_env.iop->argp->aword = ++cp;
|
global_env.iop->argp->aword = ++cp;
|
||||||
close(pf[1]);
|
close(pf[1]);
|
||||||
PUSHIO(afile, remap(pf[0]),
|
PUSHIO(afile, remap(pf[0]),
|
||||||
|
Loading…
Reference in New Issue
Block a user