Module Name:    src
Committed By:   pooka
Date:           Wed Feb 16 17:56:46 UTC 2011

Modified Files:
        src/lib/librumpclient: rumpclient.c rumpclient.h
        src/lib/librumphijack: hijack.c

Log Message:
Support vfork.  Add rumpclient wrapper for daemon(3).


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.7 -r1.8 src/lib/librumpclient/rumpclient.h
cvs rdiff -u -r1.42 -r1.43 src/lib/librumphijack/hijack.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpclient/rumpclient.c
diff -u src/lib/librumpclient/rumpclient.c:1.30 src/lib/librumpclient/rumpclient.c:1.31
--- src/lib/librumpclient/rumpclient.c:1.30	Wed Feb 16 15:33:47 2011
+++ src/lib/librumpclient/rumpclient.c	Wed Feb 16 17:56:46 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.30 2011/02/16 15:33:47 pooka Exp $	*/
+/*      $NetBSD: rumpclient.c,v 1.31 2011/02/16 17:56:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -803,6 +803,8 @@
 
 struct rumpclient_fork {
 	uint32_t fork_auth[AUTHLEN];
+	struct spclient fork_spc;
+	int fork_kq;
 };
 
 struct rumpclient_fork *
@@ -828,6 +830,9 @@
 	memcpy(rpf->fork_auth, resp, sizeof(rpf->fork_auth));
 	free(resp);
 
+	rpf->fork_spc = clispc;
+	rpf->fork_kq = kq;
+
  out:
 	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 	return rpf;
@@ -863,6 +868,21 @@
 }
 
 void
+rumpclient_fork_cancel(struct rumpclient_fork *rpf)
+{
+
+	/* EUNIMPL */
+}
+
+void
+rumpclient_fork_vparent(struct rumpclient_fork *rpf)
+{
+
+	clispc = rpf->fork_spc;
+	kq = rpf->fork_kq;
+}
+
+void
 rumpclient_setconnretry(time_t timeout)
 {
 
@@ -930,27 +950,10 @@
 }
 
 pid_t
-rumpclient_fork(pid_t (*forkfn)(void))
+rumpclient_fork()
 {
-	struct rumpclient_fork *rf;
-	pid_t rv;
-
-	if ((rf = rumpclient_prefork()) == NULL)
-		return -1;
-                
-	switch ((rv = forkfn())) {
-	case -1:
-		/* XXX: cancel rf */
-		break;
-	case 0:
-		if (rumpclient_fork_init(rf) == -1)
-			rv = -1;
-		break;
-	default:
-		break;
-	}
 
-	return rv;
+	return rumpclient__dofork(fork);
 }
 
 /*
@@ -1015,3 +1018,25 @@
 	errno = sverrno;
 	return rv;
 }
+
+int
+rumpclient_daemon(int nochdir, int noclose)
+{
+	struct rumpclient_fork *rf;
+	int sverrno;
+
+	if ((rf = rumpclient_prefork()) == NULL)
+		return -1;
+
+	if (daemon(nochdir, noclose) == -1) {
+		sverrno = errno;
+		rumpclient_fork_cancel(rf);
+		errno = sverrno;
+		return -1;
+	}
+
+	if (rumpclient_fork_init(rf) == -1)
+		return -1;
+
+	return 0;
+}

Index: src/lib/librumpclient/rumpclient.h
diff -u src/lib/librumpclient/rumpclient.h:1.7 src/lib/librumpclient/rumpclient.h:1.8
--- src/lib/librumpclient/rumpclient.h:1.7	Wed Feb 16 15:33:47 2011
+++ src/lib/librumpclient/rumpclient.h	Wed Feb 16 17:56:46 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpclient.h,v 1.7 2011/02/16 15:33:47 pooka Exp $	*/
+/*	$NetBSD: rumpclient.h,v 1.8 2011/02/16 17:56:46 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -30,17 +30,23 @@
 
 #include <sys/types.h>
 
+struct rumpclient_fork;
+
+#define rumpclient_vfork() rumpclient__dofork(vfork)
+
 __BEGIN_DECLS
 
 int rumpclient_syscall(int, const void *, size_t, register_t *);
 int rumpclient_init(void);
 
-struct rumpclient_fork;
 struct rumpclient_fork *rumpclient_prefork(void);
 int			rumpclient_fork_init(struct rumpclient_fork *);
+void			rumpclient_fork_cancel(struct rumpclient_fork *);
+void			rumpclient_fork_vparent(struct rumpclient_fork *);
 
-int rumpclient_fork(pid_t (*forkfn)(void));
+int rumpclient_fork(void);
 int rumpclient_exec(const char *, char *const [], char *const[]);
+int rumpclient_daemon(int, int);
 
 #define RUMPCLIENT_RETRYCONN_INFTIME ((time_t)-1)
 #define RUMPCLIENT_RETRYCONN_ONCE ((time_t)-2)
@@ -54,6 +60,39 @@
 };
 int rumpclient__closenotify(int *, enum rumpclient_closevariant);
 
+/*
+ * vfork needs to be implemented as an inline to make everything
+ * run in the caller's stackframe.
+ */
+static inline pid_t
+rumpclient__dofork(pid_t (*forkfn)(void))
+{
+	struct rumpclient_fork *rf;
+	pid_t pid;
+	int childran = 0;
+
+	if ((rf = rumpclient_prefork()) == NULL)
+		return -1;
+                
+	switch ((pid = forkfn())) {
+	case -1:
+		rumpclient_fork_cancel(rf);
+		break;
+	case 0:
+		childran = 1;
+		if (rumpclient_fork_init(rf) == -1)
+			pid = -1;
+		break;
+	default:
+		/* XXX: multithreaded vforker?  do they exist? */
+		if (childran)
+			rumpclient_fork_vparent(rf);
+		break;
+	}
+
+	return pid;
+}
+
 __END_DECLS
 
 #endif /* _RUMP_RUMPCLIENT_H_ */

Index: src/lib/librumphijack/hijack.c
diff -u src/lib/librumphijack/hijack.c:1.42 src/lib/librumphijack/hijack.c:1.43
--- src/lib/librumphijack/hijack.c:1.42	Wed Feb 16 15:33:46 2011
+++ src/lib/librumphijack/hijack.c	Wed Feb 16 17:56:46 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.42 2011/02/16 15:33:46 pooka Exp $	*/
+/*      $NetBSD: hijack.c,v 1.43 2011/02/16 17:56:46 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.42 2011/02/16 15:33:46 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.43 2011/02/16 17:56:46 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -601,11 +601,13 @@
 
 	DPRINTF(("fork\n"));
 
-	rv = rumpclient_fork(host_fork);
+	rv = rumpclient__dofork(host_fork);
 
 	DPRINTF(("fork returns %d\n", rv));
 	return rv;
 }
+/* we do not have the luxury of not requiring a stackframe */
+__strong_alias(__vfork14,fork);
 
 int
 daemon(int nochdir, int noclose)

Reply via email to