summaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/vfork_daemon_rexec.c9
-rw-r--r--libbb/xfuncs.c13
2 files changed, 16 insertions, 6 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 89ae9a7..ec8b9b1 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -40,11 +40,14 @@ pid_t spawn(char **argv)
* (but don't run atexit() stuff, which would screw up parent.)
*/
failed = errno;
- _exit(0);
+ _exit(111);
}
/* parent */
- /* Unfortunately, this is not reliable: vfork()
- * can be equivalent to fork() according to standards */
+ /* Unfortunately, this is not reliable: according to standards
+ * vfork() can be equivalent to fork() and we won't see value
+ * of 'failed'.
+ * Interested party can wait on pid and learn exit code.
+ * If 111 - then it (most probably) failed to exec */
if (failed) {
errno = failed;
return -1;
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 14bd62a..7f870ac 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -192,9 +192,16 @@ int wait4pid(int pid)
{
int status;
- if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1;
- if (WIFEXITED(status)) return WEXITSTATUS(status);
- if (WIFSIGNALED(status)) return WTERMSIG(status);
+ if (pid <= 0) {
+ errno = ECHILD;
+ return -1;
+ }
+ if (waitpid(pid, &status, 0) == -1)
+ return -1;
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ return WTERMSIG(status) + 10000;
return 0;
}