sbase

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

commit f24772dcbb411c631b31cae61717a60c8568bc28
parent e54eb9f4bcf9f87a8ab1adf4b22cf3740fe29161
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Sat Jun 18 06:41:28 +0100

add nohup
Diffstat:
Makefile | 19+++++++++++--------
nohup.1 | 15+++++++++++++++
nohup.c | 40++++++++++++++++++++++++++++++++++++++++
util.h | 1+
util/enprintf.c | 15+++++++++++++++
util/eprintf.c | 12+++---------
util/venprintf.c | 18++++++++++++++++++
7 files changed, 103 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile @@ -2,14 +2,16 @@ include config.mk HDR = text.h util.h LIB = \ - util/afgets.o \ - util/agetcwd.o \ - util/concat.o \ - util/enmasse.o \ - util/eprintf.o \ - util/estrtol.o \ - util/putword.o \ - util/recurse.o \ + util/afgets.o \ + util/agetcwd.o \ + util/concat.o \ + util/enmasse.o \ + util/eprintf.o \ + util/enprintf.o \ + util/estrtol.o \ + util/putword.o \ + util/recurse.o \ + util/venprintf.o SRC = \ basename.c \ @@ -31,6 +33,7 @@ SRC = \ mkdir.c \ mkfifo.c \ nl.c \ + nohup.c \ pwd.c \ rm.c \ sleep.c \ diff --git a/nohup.1 b/nohup.1 @@ -0,0 +1,15 @@ +.TH NOHUP 1 sbase\-VERSION +.SH NAME +nohup \- run a command immune to hangups +.SH SYNOPSIS +.B nohup +.I command +.RI [ argument ...] +.SH DESCRIPTION +.B nohup +runs the given command with the SIGHUP signal set to be ignored. If stdout is a +tty, it is appended to +.I nohup.out +in the current working directory; if stderr is a tty, it is redirected to stdout. +.SH SEE ALSO +.IR signal (7) diff --git a/nohup.c b/nohup.c @@ -0,0 +1,40 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> +#include "util.h" + +enum { Error = 127, Found = 126 }; + +int +main(int argc, char *argv[]) +{ + int fd; + struct sigaction sa; + + if(getopt(argc, argv, "") != -1) + exit(Error); + if(optind == argc) + enprintf(Error, "usage: %s command [argument...]\n", argv[0]); + + sa.sa_handler = SIG_IGN; + if(sigaction(SIGHUP, &sa, NULL) == -1) + enprintf(Error, "sigaction HUP:"); + if(isatty(STDOUT_FILENO)) { + if((fd = open("nohup.out", O_APPEND|O_CREAT, S_IRUSR|S_IWUSR)) == -1) + enprintf(Error, "open nohup.out:"); + if(dup2(fd, STDOUT_FILENO) == -1) + enprintf(Error, "dup2:"); + close(fd); + } + if(isatty(STDERR_FILENO)) + if(dup2(STDOUT_FILENO, STDERR_FILENO) == -1) + enprintf(Error, "dup2:"); + + execvp(argv[optind], &argv[optind]); + enprintf(errno == ENOENT ? Error : Found, "exec %s:", argv[optind]); + return Error; +} diff --git a/util.h b/util.h @@ -5,6 +5,7 @@ char *agetcwd(void); void enmasse(int, char **, int (*)(const char *, const char *)); void eprintf(const char *, ...); +void enprintf(int, const char *, ...); long estrtol(const char *, int); void putword(const char *); void recurse(const char *, void (*)(const char *)); diff --git a/util/enprintf.c b/util/enprintf.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include "../util.h" + +extern void venprintf(int, const char *, va_list); + +void +enprintf(int status, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + venprintf(status, fmt, ap); + va_end(ap); +} diff --git a/util/eprintf.c b/util/eprintf.c @@ -1,22 +1,16 @@ /* See LICENSE file for copyright and license details. */ #include <stdarg.h> -#include <stdio.h> #include <stdlib.h> -#include <string.h> #include "../util.h" +extern void venprintf(int, const char *, va_list); + void eprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + venprintf(EXIT_FAILURE, fmt, ap); va_end(ap); - - if(fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } - exit(EXIT_FAILURE); } diff --git a/util/venprintf.c b/util/venprintf.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../util.h" + +void +venprintf(int status, const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); + + if(fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } + exit(status); +}