From 0dca115912f5d64c96f14876fff3bd582a8c4a1b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 7 Apr 2009 05:52:48 +0000 Subject: implement daemon() using clone() on no-mmu systems as suggested by Jamie Lokier --- libc/unistd/Makefile.in | 2 -- libc/unistd/daemon.c | 39 ++++++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 15 deletions(-) (limited to 'libc') diff --git a/libc/unistd/Makefile.in b/libc/unistd/Makefile.in index f6ef98cf0..b4c5130a9 100644 --- a/libc/unistd/Makefile.in +++ b/libc/unistd/Makefile.in @@ -14,8 +14,6 @@ CSRC := $(filter-out exec.c,$(CSRC)) ifeq ($(ARCH_USE_MMU),y) CSRC := $(filter-out __exec_alloc.c,$(CSRC)) -else -CSRC := $(filter-out daemon.c,$(CSRC)) endif ifeq ($(UCLIBC_HAS_GNU_GETOPT),y) diff --git a/libc/unistd/daemon.c b/libc/unistd/daemon.c index 5bd6f39ed..19332cca1 100644 --- a/libc/unistd/daemon.c +++ b/libc/unistd/daemon.c @@ -56,27 +56,40 @@ /* libc_hidden_proto(chdir) */ /* libc_hidden_proto(fork) */ +#ifndef __ARCH_USE_MMU__ +#include +/* use clone() to get fork() like behavior here -- we just want to disassociate + * from the controlling terminal + */ +static inline pid_t fork_parent(void) +{ + register unsigned long ret = INTERNAL_SYSCALL(clone, wtf, 2, CLONE_VM, 0); + if (ret != -1 && ret != 0) + /* parent needs to die now w/out touching stack */ + INTERNAL_SYSCALL(exit, wtf, 0); + return ret; +} +#else +static inline pid_t fork_parent(void) +{ + switch (fork()) { + case -1: return -1; + case 0: return 0; + default: _exit(0); + } +} +#endif + int daemon( int nochdir, int noclose ) { int fd; - switch (fork()) { - case -1: - return(-1); - case 0: - break; - default: - _exit(0); - } + if (fork_parent() == -1) + return -1; if (setsid() == -1) return(-1); - /* Make certain we are not a session leader, or else we - * might reacquire a controlling terminal */ - if (fork()) - _exit(0); - if (!nochdir) chdir("/"); -- cgit v1.2.3