aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter <petershh@disroot.org>2022-07-28 15:27:09 +0300
committerGitHub <noreply@github.com>2022-07-28 15:27:09 +0300
commitf86f34feff33016eba52d778fa504ade183ee84b (patch)
tree664eecbe6afa35788ea4e461c7f351b727284468
parent4e0523ea0e26a32636ee50e286eebf3ff93cc8a7 (diff)
downloadshh-portable-utils-f86f34feff33016eba52d778fa504ade183ee84b.tar.xz
Add nohup
-rw-r--r--.gitignore1
-rw-r--r--package/deps.mak3
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak1
-rw-r--r--src/shh-portable-utils/deps-exe/nohup1
-rw-r--r--src/shh-portable-utils/nohup.c89
6 files changed, 96 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index f9e5d40..ba180f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ src/include/shh-portable-utils/config.h
/link
/ln
/nice
+/nohup
/renice
/tee
/true
diff --git a/package/deps.mak b/package/deps.mak
index d67c79a..09c9583 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -14,6 +14,7 @@ src/shh-portable-utils/false.o src/shh-portable-utils/false.lo: src/shh-portable
src/shh-portable-utils/link.o src/shh-portable-utils/link.lo: src/shh-portable-utils/link.c
src/shh-portable-utils/ln.o src/shh-portable-utils/ln.lo: src/shh-portable-utils/ln.c
src/shh-portable-utils/nice.o src/shh-portable-utils/nice.lo: src/shh-portable-utils/nice.c
+src/shh-portable-utils/nohup.o src/shh-portable-utils/nohup.lo: src/shh-portable-utils/nohup.c
src/shh-portable-utils/parse_group.o src/shh-portable-utils/parse_group.lo: src/shh-portable-utils/parse_group.c
src/shh-portable-utils/parse_user.o src/shh-portable-utils/parse_user.lo: src/shh-portable-utils/parse_user.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/renice.o src/shh-portable-utils/renice.lo: src/shh-portable-utils/renice.c src/shh-portable-utils/shhfuncs.h
@@ -46,6 +47,8 @@ ln: EXTRA_LIBS := -lskarnet
ln: src/shh-portable-utils/ln.o
nice: EXTRA_LIBS := -lskarnet
nice: src/shh-portable-utils/nice.o
+nohup: EXTRA_LIBS := -lskarnet
+nohup: src/shh-portable-utils/nohup.o
renice: EXTRA_LIBS := -lskarnet
renice: src/shh-portable-utils/renice.o src/shh-portable-utils/parse_user.o
tee: EXTRA_LIBS := -lskarnet
diff --git a/package/modes b/package/modes
index f65e285..40c11ba 100644
--- a/package/modes
+++ b/package/modes
@@ -9,6 +9,7 @@ false 0755
link 0755
ln 0755
nice 0755
+nohup 0755
renice 0755
tee 0755
true 0755
diff --git a/package/targets.mak b/package/targets.mak
index 8d0f48d..23fe74d 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -10,6 +10,7 @@ false \
link \
ln \
nice \
+nohup \
renice \
tee \
true \
diff --git a/src/shh-portable-utils/deps-exe/nohup b/src/shh-portable-utils/deps-exe/nohup
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/shh-portable-utils/deps-exe/nohup
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/shh-portable-utils/nohup.c b/src/shh-portable-utils/nohup.c
new file mode 100644
index 0000000..8036940
--- /dev/null
+++ b/src/shh-portable-utils/nohup.c
@@ -0,0 +1,89 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include <skalibs/strerr2.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#define USAGE "nohup utility [argument...]"
+
+int open_nohupout(void);
+
+int main(int argc, char **argv)
+{
+ int new_fd;
+ int stdout_tty = 0, stdout_closed = 0;
+ int stderr_tty = 0;
+
+ PROG = "nohup";
+ if (argc < 2)
+ strerr_dieusage(127, USAGE);
+
+ if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
+ strerr_diefu1sys(127, "set SIGHUP disposition");
+
+ stdout_tty = isatty(1);
+ if (errno == EBADF)
+ stdout_closed = 1;
+
+ stderr_tty = isatty(2);
+
+ /* configure io streams
+ *
+ * stdin */
+ if (stdout_tty) {
+ new_fd = open_nohupout();
+
+ if (dup2(new_fd, 1) == -1)
+ strerr_diefu1sys(127, "redirect stdin");
+
+ close(new_fd);
+ }
+
+ /* stderr */
+
+ if (stderr_tty) {
+ if (!stdout_closed) {
+ if (dup2(1, 2) == -1)
+ strerr_diefu1sys(127, "redirect stderr to stdin");
+ } else {
+ new_fd = open_nohupout();
+ if (dup2(new_fd, 2) == -1)
+ strerr_diefu1sys(127, "redirect stderr");
+ close(new_fd);
+ }
+ }
+
+ execvp(argv[1], argv + 1);
+
+ if (errno == ENOENT)
+ return 127;
+ else
+ return 126;
+}
+
+int open_nohupout(void)
+{
+ char *homedir;
+ int homedir_fd;
+ int fd = open3("nohup.out", O_WRONLY | O_CREAT | O_APPEND, 0600);
+ if (fd == -1) {
+ strerr_warnwu1sys("open nohup.out");
+ homedir = getenv("HOME");
+ if (!homedir)
+ strerr_diefu1x(127, "get $HOME value");
+ homedir_fd = open2(homedir, O_RDONLY);
+ if (homedir_fd == -1)
+ strerr_diefu1sys(127, "open home directory");
+ fd = openat(homedir_fd, "nohup.out", O_WRONLY | O_CREAT | O_APPEND,
+ 0600);
+ if (fd == -1)
+ strerr_diefu3sys(127, "open ", homedir, "/nohup.out");
+ close(homedir_fd);
+ }
+ return fd;
+}