Module Name:    src
Committed By:   pooka
Date:           Wed Feb 16 15:33:47 UTC 2011

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

Log Message:
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).


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.6 -r1.7 src/lib/librumpclient/rumpclient.h
cvs rdiff -u -r1.41 -r1.42 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.29 src/lib/librumpclient/rumpclient.c:1.30
--- src/lib/librumpclient/rumpclient.c:1.29	Tue Feb 15 10:37:07 2011
+++ src/lib/librumpclient/rumpclient.c	Wed Feb 16 15:33:47 2011
@@ -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);
-
-	newenv[nelem1+nelem2] = envstr;
-	newenv[nelem1+nelem2+1] = envstr2;
-	newenv[nelem1+nelem2+2] = NULL;
-
-	*newenvp = newenv;
+	memcpy(&newenv[0], envp, nelem*sizeof(*envp));
 
-	return 0;
+	newenv[nelem] = envstr;
+	newenv[nelem+1] = envstr2;
+	newenv[nelem+2] = NULL;
+
+	rv = host_execve(path, argv, newenv);
+
+	_DIAGASSERT(rv != 0);
+	sverrno = errno;
+	free(envstr2);
+	free(envstr);
+	free(newenv);
+	errno = sverrno;
+	return rv;
 }

Index: src/lib/librumpclient/rumpclient.h
diff -u src/lib/librumpclient/rumpclient.h:1.6 src/lib/librumpclient/rumpclient.h:1.7
--- src/lib/librumpclient/rumpclient.h:1.6	Mon Feb 14 14:56:23 2011
+++ src/lib/librumpclient/rumpclient.h	Wed Feb 16 15:33:47 2011
@@ -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
 

Index: src/lib/librumphijack/hijack.c
diff -u src/lib/librumphijack/hijack.c:1.41 src/lib/librumphijack/hijack.c:1.42
--- src/lib/librumphijack/hijack.c:1.41	Tue Feb 15 14:01:52 2011
+++ src/lib/librumphijack/hijack.c	Wed Feb 16 15:33:46 2011
@@ -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;
-
-	rv = host_execve(path, argv, env);
-	if (rv != 0) {
+	for (nelem = 0; envp && envp[nelem]; nelem++)
+		continue;
+	newenv = malloc(sizeof(*newenv) * nelem+2);
+	if (newenv == NULL) {
 		free(dup2str);
-		free(env); /* XXX missing some strings within env */
+		return ENOMEM;
 	}
+	memcpy(newenv, envp, nelem*sizeof(*newenv));
+	newenv[nelem] = dup2str;
+	newenv[nelem+1] = NULL;
+
+	rv = rumpclient_exec(path, argv, newenv);
+
+	_DIAGASSERT(rv != 0);
+	sverrno = errno;
+	free(newenv);
+	free(dup2str);
+	errno = sverrno;
 	return rv;
 }
 

Reply via email to