[git commit 0_9_30] implement daemon() using clone() on no-mmu systems as suggested by Jamie Lokier

Mike Frysinger vapier at gentoo.org
Sat Oct 10 16:44:02 UTC 2009


commit: http://git.uclibc.org/uClibc/commit/?id=ade3d86f30f5f087ed3da1290d4cbb6168d00fcf
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/0_9_30

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 include/unistd.h        |    2 --
 libc/unistd/Makefile.in |    2 --
 libc/unistd/daemon.c    |   39 ++++++++++++++++++++++++++-------------
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/include/unistd.h b/include/unistd.h
index f981d21..3efcf18 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -904,12 +904,10 @@ extern void endusershell (void) __THROW; /* Discard cached info.  */
 extern void setusershell (void) __THROW; /* Rewind and re-read the file.  */
 
 
-#ifdef __ARCH_USE_MMU__
 /* Put the program in the background, and dissociate from the controlling
    terminal.  If NOCHDIR is zero, do `chdir ("/")'.  If NOCLOSE is zero,
    redirects stdin, stdout, and stderr to /dev/null.  */
 extern int daemon (int __nochdir, int __noclose) __THROW __wur;
-#endif
 #endif /* Use BSD || X/Open.  */
 
 
diff --git a/libc/unistd/Makefile.in b/libc/unistd/Makefile.in
index b447a85..3e6ee43 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 d565ed4..ed6c381 100644
--- a/libc/unistd/daemon.c
+++ b/libc/unistd/daemon.c
@@ -56,27 +56,40 @@ libc_hidden_proto(setsid)
 libc_hidden_proto(chdir)
 libc_hidden_proto(fork)
 
+#ifndef __ARCH_USE_MMU__
+#include <sys/syscall.h>
+/* 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("/");
 
-- 
1.6.3.3



More information about the uClibc-cvs mailing list