aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-10-22 19:48:15 -0500
committerRob Landley <rob@landley.net>2020-10-22 19:48:15 -0500
commit660e6a384d8c7b32a8486a0aeb31f75939a99b75 (patch)
tree7607378be349e3ac4a7df9099c9a0075520f16e1
parent0030729a09896602b55571afb8be7fa9b29b730c (diff)
downloadtoybox-660e6a384d8c7b32a8486a0aeb31f75939a99b75.tar.gz
Add nommu-able xvdaemon() and use it to remove some TOYBOX_FORK dependencies
-rw-r--r--lib/lib.h3
-rw-r--r--lib/xwrap.c24
-rw-r--r--toys/net/sntp.c5
-rw-r--r--toys/other/watchdog.c3
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);