Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib Push the fiddly tasks for exec and fork from rumphijack ...
details: https://anonhg.NetBSD.org/src/rev/48b9f8593f31
branches: trunk
changeset: 762130:48b9f8593f31
user: pooka <pooka%NetBSD.org@localhost>
date: Wed Feb 16 15:33:46 2011 +0000
description:
Push the fiddly tasks for exec and fork from rumphijack to rumpclient.
This makes it possible easily execute those operations also from
non-hijacked rump clients (plus fixes one memory leak in an error
branch).
diffstat:
lib/librumpclient/rumpclient.c | 74 +++++++++++++++++++++++++++--------------
lib/librumpclient/rumpclient.h | 6 ++-
lib/librumphijack/hijack.c | 60 +++++++++++++--------------------
3 files changed, 77 insertions(+), 63 deletions(-)
diffs (265 lines):
diff -r 5a2d3a036c68 -r 48b9f8593f31 lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c Wed Feb 16 13:15:49 2011 +0000
+++ b/lib/librumpclient/rumpclient.c Wed Feb 16 15:33:46 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpclient.c,v 1.29 2011/02/15 10:37:07 pooka Exp $ */
+/* $NetBSD: rumpclient.c,v 1.30 2011/02/16 15:33:47 pooka Exp $ */
/*
* Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
@@ -74,6 +74,8 @@
int (*host_kevent)(int, const struct kevent *, size_t,
struct kevent *, size_t, const struct timespec *);
+int (*host_execve)(const char *, char *const[], char *const[]);
+
#include "sp_common.c"
static struct spclient clispc = {
@@ -748,6 +750,7 @@
FINDSYM(setsockopt);
FINDSYM(dup);
FINDSYM(kqueue);
+ FINDSYM(execve);
#if !__NetBSD_Prereq__(5,99,7)
FINDSYM(kevent);
#else
@@ -813,7 +816,7 @@
pthread_sigmask(SIG_SETMASK, &fullset, &omask);
rpf = malloc(sizeof(*rpf));
if (rpf == NULL)
- return NULL;
+ goto out;
if ((rv = prefork_req(&clispc, &omask, &resp)) != 0) {
free(rpf);
@@ -926,6 +929,30 @@
return 0;
}
+pid_t
+rumpclient_fork(pid_t (*forkfn)(void))
+{
+ 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;
+}
+
/*
* Process is about to exec. Save info about our existing connection
* in the env. rumpclient will check for this info in init().
@@ -933,13 +960,13 @@
* may use it as well.
*/
int
-rumpclient__exec_augmentenv(char *const oenv1[], char *const oenv2[],
- char ***newenvp)
+rumpclient_exec(const char *path, char *const argv[], char *const envp[])
{
char buf[4096];
char **newenv;
char *envstr, *envstr2;
- size_t nelem1, nelem2;
+ size_t nelem;
+ int rv, sverrno;
snprintf(buf, sizeof(buf), "RUMPCLIENT__EXECFD=%d,%d",
clispc.spc_fd, kq);
@@ -963,31 +990,28 @@
envstr2 = NULL;
}
- nelem1 = 0;
- if (oenv1) {
- for (; oenv1[nelem1]; nelem1++)
- continue;
- }
- nelem2 = 0;
- if (oenv2) {
- for (; oenv2[nelem2]; nelem2++)
- continue;
- }
+ for (nelem = 0; envp && envp[nelem]; nelem++)
+ continue;
- newenv = malloc(sizeof(*newenv) * nelem1+nelem2+3);
+ newenv = malloc(sizeof(*newenv) * nelem+3);
if (newenv == NULL) {
free(envstr2);
free(envstr);
return ENOMEM;
}
- memcpy(&newenv[0], oenv1, sizeof(*oenv1) * nelem1);
- memcpy(&newenv[nelem1], oenv2, sizeof(*oenv2) * nelem2);
+ memcpy(&newenv[0], envp, nelem*sizeof(*envp));
+
+ newenv[nelem] = envstr;
+ newenv[nelem+1] = envstr2;
+ newenv[nelem+2] = NULL;
+
+ rv = host_execve(path, argv, newenv);
- newenv[nelem1+nelem2] = envstr;
- newenv[nelem1+nelem2+1] = envstr2;
- newenv[nelem1+nelem2+2] = NULL;
-
- *newenvp = newenv;
-
- return 0;
+ _DIAGASSERT(rv != 0);
+ sverrno = errno;
+ free(envstr2);
+ free(envstr);
+ free(newenv);
+ errno = sverrno;
+ return rv;
}
diff -r 5a2d3a036c68 -r 48b9f8593f31 lib/librumpclient/rumpclient.h
--- a/lib/librumpclient/rumpclient.h Wed Feb 16 13:15:49 2011 +0000
+++ b/lib/librumpclient/rumpclient.h Wed Feb 16 15:33:46 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpclient.h,v 1.6 2011/02/14 14:56:23 pooka Exp $ */
+/* $NetBSD: rumpclient.h,v 1.7 2011/02/16 15:33:47 pooka Exp $ */
/*-
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -39,6 +39,9 @@
struct rumpclient_fork *rumpclient_prefork(void);
int rumpclient_fork_init(struct rumpclient_fork *);
+int rumpclient_fork(pid_t (*forkfn)(void));
+int rumpclient_exec(const char *, char *const [], char *const[]);
+
#define RUMPCLIENT_RETRYCONN_INFTIME ((time_t)-1)
#define RUMPCLIENT_RETRYCONN_ONCE ((time_t)-2)
#define RUMPCLIENT_RETRYCONN_DIE ((time_t)-3)
@@ -50,7 +53,6 @@
RUMPCLIENT_CLOSE_FCLOSEM
};
int rumpclient__closenotify(int *, enum rumpclient_closevariant);
-int rumpclient__exec_augmentenv(char *const[], char *const[], char ***);
__END_DECLS
diff -r 5a2d3a036c68 -r 48b9f8593f31 lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c Wed Feb 16 13:15:49 2011 +0000
+++ b/lib/librumphijack/hijack.c Wed Feb 16 15:33:46 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hijack.c,v 1.41 2011/02/15 14:01:52 pooka Exp $ */
+/* $NetBSD: hijack.c,v 1.42 2011/02/16 15:33: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.41 2011/02/15 14:01:52 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.42 2011/02/16 15:33:46 pooka Exp $");
#define __ssp_weak_name(fun) _hijack_ ## fun
@@ -594,33 +594,14 @@
return dodup(oldd, 0);
}
-/*
- * We just wrap fork the appropriate rump client calls to preserve
- * the file descriptors of the forked parent in the child, but
- * prevent double use of connection fd.
- */
pid_t
fork()
{
- struct rumpclient_fork *rf;
pid_t rv;
DPRINTF(("fork\n"));
- if ((rf = rumpclient_prefork()) == NULL)
- return -1;
-
- switch ((rv = host_fork())) {
- case -1:
- /* XXX: cancel rf */
- break;
- case 0:
- if (rumpclient_fork_init(rf) == -1)
- rv = -1;
- break;
- default:
- break;
- }
+ rv = rumpclient_fork(host_fork);
DPRINTF(("fork returns %d\n", rv));
return rv;
@@ -644,31 +625,38 @@
}
int
-execve(const char *path, char *const argv[], char *const oenvp[])
+execve(const char *path, char *const argv[], char *const envp[])
{
char buf[128];
- char **env;
- char *dup2maskenv[2];
char *dup2str;
- int rv;
+ char **newenv;
+ size_t nelem;
+ int rv, sverrno;
snprintf(buf, sizeof(buf), "RUMPHIJACK__DUP2MASK=%u", dup2mask);
dup2str = malloc(strlen(buf)+1);
if (dup2str == NULL)
return ENOMEM;
strcpy(dup2str, buf);
- dup2maskenv[0] = dup2str;
- dup2maskenv[1] = NULL;
- rv = rumpclient__exec_augmentenv(oenvp, dup2maskenv, &env);
- if (rv)
- return rv;
+ for (nelem = 0; envp && envp[nelem]; nelem++)
+ continue;
+ newenv = malloc(sizeof(*newenv) * nelem+2);
+ if (newenv == NULL) {
+ free(dup2str);
+ return ENOMEM;
+ }
+ memcpy(newenv, envp, nelem*sizeof(*newenv));
+ newenv[nelem] = dup2str;
+ newenv[nelem+1] = NULL;
- rv = host_execve(path, argv, env);
- if (rv != 0) {
- free(dup2str);
- free(env); /* XXX missing some strings within env */
- }
+ rv = rumpclient_exec(path, argv, newenv);
+
+ _DIAGASSERT(rv != 0);
+ sverrno = errno;
+ free(newenv);
+ free(dup2str);
+ errno = sverrno;
return rv;
}
Home |
Main Index |
Thread Index |
Old Index