From 660e6a384d8c7b32a8486a0aeb31f75939a99b75 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 22 Oct 2020 19:48:15 -0500 Subject: Add nommu-able xvdaemon() and use it to remove some TOYBOX_FORK dependencies --- lib/lib.h | 3 ++- lib/xwrap.c | 24 ++++++++++++++++++++++++ toys/net/sntp.c | 5 ++--- toys/other/watchdog.c | 3 +-- 4 files changed, 29 insertions(+), 6 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 diff --git a/toys/net/sntp.c b/toys/net/sntp.c index dae19485..161cab46 100644 --- a/toys/net/sntp.c +++ b/toys/net/sntp.c @@ -11,7 +11,6 @@ USE_SNTP(NEWTOY(sntp, ">1M :m :Sp:t#<0=1>16asdDqr#<4>17=10[!as]", TOYFLAG_USR|TO config SNTP bool "sntp" default y - depends on TOYBOX_FORK help usage: sntp [-saSdDq] [-r SHIFT] [-mM[ADDRESS]] [-p PORT] [SERVER] @@ -79,6 +78,8 @@ void sntp_main(void) union socksaddr sa; int fd, tries = 0; + if (FLAG(d)) xvdaemon(); + if (FLAG(M)) toys.optflags |= FLAG_S; if (!(FLAG(S)||FLAG(m)) && !*toys.optargs) error_exit("Need -SMm or SERVER address"); @@ -88,8 +89,6 @@ void sntp_main(void) ai = xgetaddrinfo(*toys.optargs, TT.p, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, AI_PASSIVE*!*toys.optargs); - if (FLAG(d) && daemon(0, 0)) perror_exit("daemonize"); - // Act as server if necessary if (FLAG(S)||FLAG(m)) { fd = xbindany(ai); diff --git a/toys/other/watchdog.c b/toys/other/watchdog.c index a2e4fa01..232d82c0 100644 --- a/toys/other/watchdog.c +++ b/toys/other/watchdog.c @@ -9,7 +9,6 @@ USE_WATCHDOG(NEWTOY(watchdog, "<1>1Ft#=4<1T#=60<1", TOYFLAG_NEEDROOT|TOYFLAG_BIN config WATCHDOG bool "watchdog" default y - depends on TOYBOX_FORK help usage: watchdog [-F] [-t UPDATE] [-T DEADLINE] DEV @@ -38,7 +37,7 @@ void safe_shutdown(int ignored) { void watchdog_main(void) { - if (!FLAG(F) && daemon(1, 1)) perror_exit("failed to daemonize"); + if (!FLAG(F)) xvdaemon(); xsignal(SIGTERM, safe_shutdown); xsignal(SIGINT, safe_shutdown); xioctl(TT.fd = xopen(*toys.optargs, O_WRONLY), WDIOC_SETTIMEOUT, &TT.T); -- cgit v1.2.3