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)