From 6f207dac5ff858aac6827a4cd4ac78aa5d07a801 Mon Sep 17 00:00:00 2001 From: FRIGN Date: Mon, 9 Mar 2015 01:04:34 +0100 Subject: [PATCH] Don't return but _exit after failed exec*() and fork() Quoting POSIX[0]: "Care should be taken, also, to call _exit() rather than exit() if exec cannot be used, since exit() flushes and closes standard I/O channels, thereby damaging the parent process' standard I/O data structures. (Even with fork(), it is wrong to call exit(), since buffered data would then be flushed twice.)" [0]: http://pubs.opengroup.org/onlinepubs/009695399/functions/vfork.html --- chroot.c | 7 +++---- env.c | 6 +++++- nice.c | 2 +- nohup.c | 5 ++--- setsid.c | 5 +++-- tar.c | 14 ++++++++------ time.c | 5 +++-- xargs.c | 8 +++++--- 8 files changed, 30 insertions(+), 22 deletions(-) diff --git a/chroot.c b/chroot.c index 5048c78..beec628 100644 --- a/chroot.c +++ b/chroot.c @@ -36,15 +36,14 @@ main(int argc, char *argv[]) if (argc == 1) { cmd = *shell; - execvp(*shell, shell); + execvp(cmd, shell); } else { cmd = argv[1]; - execvp(argv[1], argv + 1); + execvp(cmd, argv + 1); } savederrno = errno; weprintf("execvp %s:", cmd); - _exit(126 + (savederrno == ENOENT)); - return 0; /* not reached */ + _exit(126 + (savederrno == ENOENT)); } diff --git a/env.c b/env.c index 971514b..5af93e0 100644 --- a/env.c +++ b/env.c @@ -18,6 +18,8 @@ usage(void) int main(int argc, char *argv[]) { + int savederrno; + ARGBEGIN { case 'i': if (environ) @@ -35,7 +37,9 @@ main(int argc, char *argv[]) if (*argv) { execvp(*argv, argv); - enprintf(126 + (errno == EEXIST), "execvp: %s:", *argv); + savederrno = errno; + weprintf("execvp %s:", *argv); + _exit(126 + (savederrno == EEXIST)); } for (; environ && *environ; environ++) diff --git a/nice.c b/nice.c index 70a5c2d..d9985fa 100644 --- a/nice.c +++ b/nice.c @@ -44,5 +44,5 @@ main(int argc, char *argv[]) savederrno = errno; weprintf("execvp %s:", argv[0]); - return 126 + (savederrno == ENOENT); + _exit(126 + (savederrno == ENOENT)); } diff --git a/nohup.c b/nohup.c index 6c7b933..59970cb 100644 --- a/nohup.c +++ b/nohup.c @@ -42,8 +42,7 @@ main(int argc, char *argv[]) execvp(argv[0], argv); savederrno = errno; - weprintf("exec %s:", argv[0]); - _exit(126 + (savederrno == ENOENT)); + weprintf("execvp %s:", argv[0]); - return 0; /* not reached */ + _exit(126 + (savederrno == ENOENT)); } diff --git a/setsid.c b/setsid.c index 73c2ae8..212100b 100644 --- a/setsid.c +++ b/setsid.c @@ -26,7 +26,8 @@ main(int argc, char *argv[]) if (getpgrp() == getpid()) { switch (fork()) { case -1: - eprintf("fork:"); + weprintf("fork:"); + _exit(1); case 0: break; default: @@ -39,5 +40,5 @@ main(int argc, char *argv[]) savederrno = errno; weprintf("execvp %s:", argv[0]); - return 126 + (savederrno == ENOENT); + _exit(126 + (savederrno == ENOENT)); } diff --git a/tar.c b/tar.c index e0e6240..d847c9d 100644 --- a/tar.c +++ b/tar.c @@ -55,7 +55,8 @@ decomp(FILE *fp) pid = fork(); if (pid < 0) { - eprintf("fork:"); + weprintf("fork:"); + _exit(1); } else if (!pid) { dup2(fileno(fp), 0); dup2(fds[1], 1); @@ -64,12 +65,13 @@ decomp(FILE *fp) switch (filtermode) { case 'j': - execlp("bzip2", "bzip2", "-cd", (char *)0); - eprintf("execlp bzip2:"); + execlp("bzip2", "bzip2", "-cd", NULL); + weprintf("execlp bzip2:"); + _exit(1); case 'z': - execlp("gzip", "gzip", "-cd", (char *)0); - eprintf("execlp gzip:"); - break; + execlp("gzip", "gzip", "-cd", NULL); + weprintf("execlp gzip:"); + _exit(1); } } close(fds[1]); diff --git a/time.c b/time.c index 0b8e607..3ff25ac 100644 --- a/time.c +++ b/time.c @@ -41,11 +41,12 @@ main(int argc, char *argv[]) switch ((pid = fork())) { case -1: - eprintf("fork:"); + weprintf("fork:"); + _exit(1); case 0: execvp(argv[0], argv); savederrno = errno; - weprintf("exec %s:", argv[0]); + weprintf("execvp %s:", argv[0]); _exit(126 + (savederrno == ENOENT)); default: break; diff --git a/xargs.c b/xargs.c index 9245627..983eeb2 100644 --- a/xargs.c +++ b/xargs.c @@ -168,13 +168,15 @@ spawn(void) int savederrno; pid = fork(); - if (pid < 0) - eprintf("fork:"); + if (pid < 0) { + weprintf("fork:"); + _exit(1); + } if (pid == 0) { execvp(*cmd, cmd); savederrno = errno; weprintf("execvp %s:", *cmd); - _exit(savederrno == ENOENT ? 127 : 126); + _exit(126 + (savederrno == ENOENT)); } waitchld(); }