Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib Support vfork. Add rumpclient wrapper for daemon(3).
details: https://anonhg.NetBSD.org/src/rev/b8f9d1ce3f7f
branches: trunk
changeset: 762137:b8f9d1ce3f7f
user: pooka <pooka%NetBSD.org@localhost>
date: Wed Feb 16 17:56:46 2011 +0000
description:
Support vfork. Add rumpclient wrapper for daemon(3).
diffstat:
lib/librumpclient/rumpclient.c | 65 +++++++++++++++++++++++++++++------------
lib/librumpclient/rumpclient.h | 45 +++++++++++++++++++++++++++-
lib/librumphijack/hijack.c | 8 +++-
3 files changed, 92 insertions(+), 26 deletions(-)
diffs (214 lines):
diff -r c1382ea315e7 -r b8f9d1ce3f7f lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c Wed Feb 16 17:53:31 2011 +0000
+++ b/lib/librumpclient/rumpclient.c Wed Feb 16 17:56:46 2011 +0000
@@ -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;
+}
diff -r c1382ea315e7 -r b8f9d1ce3f7f lib/librumpclient/rumpclient.h
--- a/lib/librumpclient/rumpclient.h Wed Feb 16 17:53:31 2011 +0000
+++ b/lib/librumpclient/rumpclient.h Wed Feb 16 17:56:46 2011 +0000
@@ -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_ */
diff -r c1382ea315e7 -r b8f9d1ce3f7f lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c Wed Feb 16 17:53:31 2011 +0000
+++ b/lib/librumphijack/hijack.c Wed Feb 16 17:56:46 2011 +0000
@@ -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)
Home |
Main Index |
Thread Index |
Old Index