diff options
author | Jakob Kaivo <jkk@ung.org> | 2019-03-14 13:41:50 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2019-03-14 13:41:50 -0400 |
commit | 52b4d08cf24c987c97a2210e69251f826f34c531 (patch) | |
tree | 50a0c39dff22f8e55bd2e16b583394c3558175d5 |
first cut
-rw-r--r-- | nohup.c | 69 |
1 files changed, 69 insertions, 0 deletions
@@ -0,0 +1,69 @@ +#define _XOPEN_SOURCE 700 +#include <errno.h> +#include <fcntl.h> +#include <locale.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define NOHUP_UTILITY_NOT_FOUND 127 +#define NOHUP_UTILITY_NOT_INVOKED 126 + +int main(int argc, char *argv[]) +{ + int c; + + setlocale(LC_ALL, ""); + + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + default: + return 1; + } + } + + argv += optind; + + if (argv[0] == NULL) { + fprintf(stderr, "nohup: utility required\n"); + return NOHUP_UTILITY_NOT_INVOKED; + } + + signal(SIGHUP, SIG_IGN); + + if (isatty(STDOUT_FILENO)) { + char out[FILENAME_MAX] = "nohup.out"; + int fd = open(out, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); + if (fd == -1) { + char *home = getenv("HOME"); + if (home == NULL) { + fprintf(stderr, "nohup: $HOME unset\n"); + return NOHUP_UTILITY_NOT_INVOKED; + } + snprintf(out, sizeof(out), "%s/nohup.out", home); + fd = open(out, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); + if (fd == -1) { + perror("nohup: couldn't open nohup.out or $HOME/nohup.out"); + return NOHUP_UTILITY_NOT_INVOKED; + } + } + + fprintf(stderr, "nohup: appending to %s\n", out); + dup2(fd, STDOUT_FILENO); + } + + if (isatty(STDERR_FILENO)) { + dup2(STDOUT_FILENO, STDERR_FILENO); + } + + execvp(argv[0], argv); + + perror("nohup"); + + if (errno == ENOENT) { + return NOHUP_UTILITY_NOT_FOUND; + } + + return NOHUP_UTILITY_NOT_INVOKED; +} |