aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt10
-rw-r--r--guts/clone.c33
-rw-r--r--guts/execve.c1
-rw-r--r--guts/fork.c9
-rw-r--r--pseudo_client.c127
-rw-r--r--pseudo_client.h1
-rw-r--r--pseudo_server.c63
-rw-r--r--pseudo_wrappers.c72
8 files changed, 193 insertions, 123 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 121fe12..d1e18fc 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,13 @@
+2010-12-08:
+ * (mhatle) Add guts/clone.c to cleanup the clone support
+ * (mhatle) guts/clone.c only run setupenv and reinit when NOT PSEUDO_RELOADED
+ * (mhatle) guts/execve.c whitespace fixe
+ * (mhatle) guts/fork.c similar to guts/clone.c change
+ * (mhatle) pseudo_client.c add reinit function
+ * (mhatle) pseudo_client.c revise client reset, include code from pseudo_wrappers.c
+ * (mhatle) pseudo_server.c move the pid writing to the parent
+ * (mhatle) pseudo_wrappers.c clone cleanup and populate cleanup
+
2010-12-07:
* (seebs) whitespace fixes
* (seebs) improve fork and PSEUDO_DISABLED
diff --git a/guts/clone.c b/guts/clone.c
new file mode 100644
index 0000000..61c8bf9
--- /dev/null
+++ b/guts/clone.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * clone(...) {
+ * ....
+ */
+ /* because clone() doesn't actually continue in this function, we
+ * can't check the return and fix up environment variables in the
+ * child. Instead, we have to temporarily do any fixup, then possibly
+ * undo it later. UGH!
+ */
+ pseudo_debug(1, "client resetting for clone(2) call\n");
+ if (real_clone) {
+ if (!pseudo_get_value("PSEUDO_RELOADED")) {
+ pseudo_setupenv();
+ pseudo_client_reinit();
+ } else {
+ pseudo_setupenv();
+ pseudo_dropenv();
+ }
+ /* call the real syscall */
+ rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid);
+ } else {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("clone");
+ }
+
+/* ...
+ * return rc;
+ * }
+ */
diff --git a/guts/execve.c b/guts/execve.c
index 36d4bfd..febcf80 100644
--- a/guts/execve.c
+++ b/guts/execve.c
@@ -14,6 +14,7 @@
* design will likely be revisited.
*/
pseudo_client_op(OP_EXEC, PSA_EXEC, -1, -1, file, 0);
+
if (!pseudo_get_value("PSEUDO_RELOADED"))
new_environ = pseudo_setupenvp(envp);
else {
diff --git a/guts/fork.c b/guts/fork.c
index fa23be1..8febd13 100644
--- a/guts/fork.c
+++ b/guts/fork.c
@@ -12,8 +12,13 @@
* pseudo in the child process
*/
if (rc == 0) {
- pseudo_setupenv();
- pseudo_client_reset();
+ if (!pseudo_get_value("PSEUDO_RELOADED")) {
+ pseudo_setupenv();
+ pseudo_client_reinit();
+ } else {
+ pseudo_setupenv();
+ pseudo_dropenv();
+ }
}
} else {
/* rc was initialized to the "failure" value */
diff --git a/pseudo_client.c b/pseudo_client.c
index e30d3e7..8bad083 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -311,10 +311,16 @@ pseudo_client_close(int fd) {
fd_paths[fd] = 0;
}
+ void
+pseudo_client_reinit() {
+ pseudo_debug(1, "called: pseudo_client_reinit\n");
+ pseudo_inited = 0;
+ pseudo_reinit_environment();
+ pseudo_client_reset();
+}
+
void
pseudo_client_reset() {
- char *env_disabled = NULL;
-
pseudo_antimagic();
pseudo_new_pid();
if (connect_fd != -1) {
@@ -322,43 +328,94 @@ pseudo_client_reset() {
connect_fd = -1;
}
- /* in child processes, PSEUDO_DISABLED may have become set to
- * some truthy value, in which case we'd disable pseudo,
- * or it may have gone away, in which case we'd enable
- * pseudo.
- */
- env_disabled = getenv("PSEUDO_DISABLED");
- if (env_disabled) {
- int actually_disabled = 1;
- switch (*env_disabled) {
- case 'f':
- case 'F':
- case 'n':
- case 'N':
- actually_disabled = 0;
- break;
- case '0':
- actually_disabled = atoi(env_disabled);
- break;
+ if (!pseudo_inited) {
+ char *pseudo_path = 0;
+ char *env;
+
+ /* Ensure that all of the values are reset */
+ server_pid = 0;
+ pseudo_prefix_dir_fd = -1;
+ pseudo_localstate_dir_fd = -1;
+ pseudo_pwd_fd = -1;
+ pseudo_pwd_lck_fd = -1;
+ pseudo_pwd_lck_name = NULL;
+ pseudo_pwd = NULL;
+ pseudo_grp_fd = -1;
+ pseudo_grp = NULL;
+ pseudo_cwd = NULL;
+ pseudo_cwd_len = 0;
+ pseudo_chroot = NULL;
+ pseudo_passwd = NULL;
+ pseudo_chroot_len = 0;
+ pseudo_cwd_rel = NULL;
+
+ pseudo_path = pseudo_prefix_path(NULL);
+ if (pseudo_prefix_dir_fd == -1) {
+ if (pseudo_path) {
+ pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
+ pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, MOVE_FD);
+ } else {
+ pseudo_diag("No prefix available to to find server.\n");
+ exit(1);
+ }
+ if (pseudo_prefix_dir_fd == -1) {
+ pseudo_diag("Can't open prefix path (%s) for server: %s\n",
+ pseudo_path,
+ strerror(errno));
+ exit(1);
+ }
}
- if (actually_disabled) {
- if (!pseudo_disabled) {
- pseudo_antimagic();
- pseudo_disabled = 1;
+ free(pseudo_path);
+ pseudo_path = pseudo_localstatedir_path(NULL);
+ if (pseudo_localstate_dir_fd == -1) {
+ if (pseudo_path) {
+ pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
+ pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, MOVE_FD);
+ } else {
+ pseudo_diag("No prefix available to to find server.\n");
+ exit(1);
}
- env_disabled = "1";
- } else {
- if (pseudo_disabled) {
- pseudo_magic();
- pseudo_disabled = 0;
+ if (pseudo_localstate_dir_fd == -1) {
+ pseudo_diag("Can't open prefix path (%s) for server: %s\n",
+ pseudo_path,
+ strerror(errno));
+ exit(1);
}
- env_disabled = "0";
}
- pseudo_set_value("PSEUDO_DISABLED", env_disabled);
- }
+ free(pseudo_path);
- if (!pseudo_inited) {
- char *env;
+ /* in child processes, PSEUDO_DISABLED may have become set to
+ * some truthy value, in which case we'd disable pseudo,
+ * or it may have gone away, in which case we'd enable
+ * pseudo.
+ */
+ env = getenv("PSEUDO_DISABLED");
+ if (!env) pseudo_get_value("PSEUDO_DISABLED");
+ if (env) {
+ int actually_disabled = 1;
+ switch (*env) {
+ case '0':
+ case 'f':
+ case 'F':
+ case 'n':
+ case 'N':
+ actually_disabled = 0;
+ break;
+ }
+ if (actually_disabled) {
+ if (!pseudo_disabled) {
+ pseudo_antimagic();
+ pseudo_disabled = 1;
+ }
+ pseudo_set_value("PSEUDO_DISABLED", "1");
+ } else {
+ if (pseudo_disabled) {
+ pseudo_magic();
+ pseudo_disabled = 0;
+ }
+ pseudo_set_value("PSEUDO_DISABLED", "0");
+ }
+ }
env = pseudo_get_value("PSEUDO_UIDS");
if (env)
@@ -394,8 +451,6 @@ pseudo_client_reset() {
pseudo_inited = 1;
}
pseudo_client_getcwd();
- /* make sure environment variables are back in sync */
- pseudo_reinit_environment();
pseudo_magic();
}
diff --git a/pseudo_client.h b/pseudo_client.h
index 7eac3c8..ea92f6a 100644
--- a/pseudo_client.h
+++ b/pseudo_client.h
@@ -20,6 +20,7 @@
extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat64 *buf, ...);
extern void pseudo_antimagic(void);
extern void pseudo_magic(void);
+extern void pseudo_client_reinit(void);
extern void pseudo_client_reset(void);
extern void pseudo_client_touchuid(void);
extern void pseudo_client_touchgid(void);
diff --git a/pseudo_server.c b/pseudo_server.c
index 071614c..50425de 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -81,12 +81,33 @@ static struct timeval message_time = { .tv_sec = 0 };
static void pseudo_server_loop(void);
+static int
+pseudo_server_write_pid(pid_t pid) {
+ char *pseudo_path;
+ FILE *fp;
+
+ pseudo_path = pseudo_localstatedir_path(PSEUDO_PIDFILE);
+ if (!pseudo_path) {
+ pseudo_diag("Couldn't get path for prefix/%s\n", PSEUDO_PIDFILE);
+ return 1;
+ }
+ fp = fopen(pseudo_path, "w");
+ if (!fp) {
+ pseudo_diag("Couldn't open %s: %s\n",
+ pseudo_path, strerror(errno));
+ return 1;
+ }
+ fprintf(fp, "%lld\n", (long long) pid);
+ fclose(fp);
+ free(pseudo_path);
+ return 0;
+}
+
int
pseudo_server_start(int daemonize) {
struct sockaddr_un sun = { AF_UNIX, PSEUDO_SOCKET };
char *pseudo_path;
int rc, newfd;
- FILE *fp;
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
@@ -124,37 +145,29 @@ pseudo_server_start(int daemonize) {
pseudo_diag("couldn't listen on socket: %s\n", strerror(errno));
return 1;
}
- if (daemonize && ((rc = fork()) != 0)) {
- if (rc == -1) {
- pseudo_diag("couldn't spawn server: %s\n", strerror(errno));
- return 0;
- }
- pseudo_debug(2, "started server, pid %d\n", rc);
- close(listen_fd);
- return 0;
- }
- setsid();
- pseudo_path = pseudo_localstatedir_path(PSEUDO_PIDFILE);
- if (!pseudo_path) {
- pseudo_diag("Couldn't get path for prefix/%s\n", PSEUDO_PIDFILE);
- return 1;
- }
- fp = fopen(pseudo_path, "w");
- if (!fp) {
- pseudo_diag("Couldn't open %s: %s\n",
- pseudo_path, strerror(errno));
- return 1;
- }
- fprintf(fp, "%lld\n", (long long) getpid());
- fclose(fp);
- free(pseudo_path);
if (daemonize) {
+ if ((rc = fork()) != 0) {
+ if (rc == -1) {
+ pseudo_diag("couldn't spawn server: %s\n", strerror(errno));
+ return 0;
+ }
+ pseudo_debug(2, "started server, pid %d\n", rc);
+ close(listen_fd);
+ /* Parent writes pid, that way it's always correct */
+ return pseudo_server_write_pid(rc);
+ }
+ /* In child */
pseudo_new_pid();
fclose(stdin);
fclose(stdout);
if (!pseudo_logfile(PSEUDO_LOGFILE))
fclose(stderr);
+ } else {
+ /* Write the pid if we don't daemonize */
+ pseudo_server_write_pid(getpid());
}
+
+ setsid();
signal(SIGHUP, quit_now);
signal(SIGINT, quit_now);
signal(SIGALRM, quit_now);
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 0321fe2..ee1d3ea 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -144,7 +144,6 @@ pseudo_populate_wrappers(void) {
int i;
char *debug;
static int done = 0;
- char *pseudo_path = 0;
char *no_symlink_exp;
if (done)
@@ -206,40 +205,6 @@ pseudo_populate_wrappers(void) {
* value for cwd.
*/
pseudo_client_reset();
- pseudo_path = pseudo_prefix_path(NULL);
- if (pseudo_prefix_dir_fd == -1) {
- if (pseudo_path) {
- pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
- pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, MOVE_FD);
- } else {
- pseudo_diag("No prefix available to to find server.\n");
- exit(1);
- }
- if (pseudo_prefix_dir_fd == -1) {
- pseudo_diag("Can't open prefix path (%s) for server: %s\n",
- pseudo_path,
- strerror(errno));
- exit(1);
- }
- }
- free(pseudo_path);
- pseudo_path = pseudo_localstatedir_path(NULL);
- if (pseudo_localstate_dir_fd == -1) {
- if (pseudo_path) {
- pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
- pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, MOVE_FD);
- } else {
- pseudo_diag("No prefix available to to find server.\n");
- exit(1);
- }
- if (pseudo_localstate_dir_fd == -1) {
- pseudo_diag("Can't open prefix path (%s) for server: %s\n",
- pseudo_path,
- strerror(errno));
- exit(1);
- }
- }
- free(pseudo_path);
pseudo_debug(2, "(%s) set up wrappers\n", program_invocation_short_name);
pseudo_magic();
pseudo_droplock();
@@ -537,32 +502,17 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
* child. Instead, we have to temporarily do any fixup, then possibly
* undo it later. UGH!
*/
- pseudo_debug(1, "client resetting for clone(2) call\n");
- if (real_clone) {
- pseudo_setupenv();
- pseudo_client_reset();
- /* call the real syscall */
- rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid);
-
- /* if we got here, we're the parent process. And if we changed
- * pseudo_disabled because of the environment, now we want to
- * bring it back. We can't use the normal path for this in
- * pseudo_client_reset() because that would trust the environment
- * variable, which was intended only to modify the behavior of
- * the child process.
- */
- if (save_disabled != pseudo_disabled) {
- if (pseudo_disabled) {
- pseudo_disabled = 0;
- pseudo_magic();
- } else {
- pseudo_disabled = 1;
- pseudo_antimagic();
- }
+
+#include "guts/clone.c"
+
+ if (save_disabled != pseudo_disabled) {
+ if (pseudo_disabled) {
+ pseudo_disabled = 0;
+ pseudo_magic();
+ } else {
+ pseudo_disabled = 1;
+ pseudo_antimagic();
}
- } else {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("clone");
}
save_errno = errno;
@@ -583,9 +533,11 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
}
static int (*real_fork)(void) = NULL;
+#if 0
static int (*real_execlp)(const char *file, const char *arg, ...) = NULL;
static int (*real_execl)(const char *file, const char *arg, ...) = NULL;
static int (*real_execle)(const char *file, const char *arg, ...) = NULL;
+#endif
static int (*real_clone)(int (*)(void *), void *, int, void *, ...) = NULL;
static int