sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit 6f207dac5ff858aac6827a4cd4ac78aa5d07a801
parent 4414a17e1b79ced4e7fee8d8c6f6e549a30b16aa
Author: FRIGN <dev@frign.de>
Date:   Mon Mar  9 01:04:34 +0100

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

Diffstat:
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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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(); }