aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.h3
-rw-r--r--lib/xwrap.c24
2 files changed, 26 insertions, 1 deletions
diff --git a/lib/lib.h b/lib/lib.h
index 6851c4aa..192fb7d2 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -127,12 +127,13 @@ char *xstrndup(char *s, size_t n);
char *xstrdup(char *s);
void *xmemdup(void *s, long len);
char *xmprintf(char *format, ...) printf_format;
+void xflush(int flush);
void xprintf(char *format, ...) printf_format;
void xputsl(char *s, int len);
void xputsn(char *s);
void xputs(char *s);
void xputc(char c);
-void xflush(int flush);
+void xvdaemon(void);
void xexec(char **argv);
pid_t xpopen_setup(char **argv, int *pipes, void (*callback)(char **argv));
pid_t xpopen_both(char **argv, int *pipes);
diff --git a/lib/xwrap.c b/lib/xwrap.c
index cf7fc42a..85fa2405 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -182,6 +182,30 @@ void xputc(char c)
xflush(0);
}
+// daemonize via vfork(). Does not chdir("/"), caller should do that first
+// note: restarts process from command_main()
+void xvdaemon(void)
+{
+ int fd;
+
+ // vfork and exec /proc/self/exe
+ if (toys.stacktop) {
+ xpopen(0, 0, 0);
+ _exit(0);
+ }
+
+ // new session id, point fd 0-2 at /dev/null, detach from tty
+ setsid();
+ close(0);
+ xopen_stdio("/dev/null", O_RDWR);
+ dup2(0, 1);
+ if (-1 != (fd = open("/dev/tty", O_RDONLY))) {
+ ioctl(fd, TIOCNOTTY);
+ close(fd);
+ }
+ dup2(0, 2);
+}
+
// This is called through the XVFORK macro because parent/child of vfork
// share a stack, so child returning from a function would stomp the return
// address parent would need. Solution: make vfork() an argument so processes