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.
int wait4pid(int pid)
{
/* we expect errno to be already set from failed [v]fork/exec */
return -1;
}
- if (waitpid(pid, &status, 0) == -1)
+ if (safe_waitpid(pid, &status, 0) == -1)
return -1;
if (WIFEXITED(status))
return WEXITSTATUS(status);
return 0;
}
-int wait_nohang(int *wstat)
-{
- return waitpid(-1, wstat, WNOHANG);
-}
-
-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
void save_nofork_data(struct nofork_save_area *save)
{
applet_name = APPLET_NAME(applet_no);
xfunc_error_retval = EXIT_FAILURE;
- /*option_mask32 = 0; - not needed */
- /* special flag for xfunc_die(). If xfunc will "die"
+
+ /* Special flag for xfunc_die(). If xfunc will "die"
* in NOFORK applet, xfunc_die() sees negative
* die_sleep and longjmp here instead. */
die_sleep = -1;
+ /* option_mask32 = 0; - not needed */
+
argc = 1;
while (argv[argc])
argc++;
char *tmp_argv[argc+1];
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
/* Finally we can call NOFORK applet's main() */
- rc = applet_mains[applet_no](argc, tmp_argv);
+ rc = applet_main[applet_no](argc, tmp_argv);
+
+ /* The whole reason behind nofork_save_area is that <applet>_main
+ * may exit non-locally! For example, in hush Ctrl-Z tries
+ * (modulo bugs) to dynamically create a child (backgrounded task)
+ * if it detects that Ctrl-Z was pressed when a NOFORK was running.
+ * Testcase: interactive "rm -i".
+ * Don't fool yourself into thinking "and <applet>_main() returns
+ * quickly here" and removing "useless" nofork_save_area code. */
+
} else { /* xfunc died in NOFORK applet */
/* in case they meant to return 0... */
if (rc == -2222)
/* Restoring globals */
restore_nofork_data(old);
- return rc;
+ return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
}
int run_nofork_applet(int applet_no, char **argv)
if (pid < 0) /* wtf? */
bb_perror_msg_and_die("vfork");
if (pid) /* parent */
- exit(0);
+ exit(EXIT_SUCCESS);
/* child - re-exec ourself */
re_exec(argv);
}
if (pid < 0) /* wtf? */
bb_perror_msg_and_die("fork");
if (pid) /* parent */
- exit(0);
+ exit(EXIT_SUCCESS);
/* child */
}
#define forkexit_or_rexec(argv) forkexit_or_rexec()