aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt3
-rw-r--r--doc/program_flow16
-rw-r--r--guts/clone.c20
-rw-r--r--guts/fork.c27
-rw-r--r--pseudo_wrappers.c322
-rw-r--r--templates/wrapfuncs.c60
6 files changed, 214 insertions, 234 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 9832e4a..0c942e7 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,6 @@
+2010-12-14:
+ * (mhatle) restructure wrapfuncs.c
+
2010-12-09:
* (mhatle) Add doc/program_flow to attempt to explain startup/running
* (mhatle) guts/* minor cleanup
diff --git a/doc/program_flow b/doc/program_flow
index b0680a0..8991681 100644
--- a/doc/program_flow
+++ b/doc/program_flow
@@ -37,7 +37,7 @@ libpseudo execution flow:
fork()
clone()
- pseudo_populate_wrappers():
+ pseudo_check_wrappers():
pseudo_reinit_libpseudo if necessary
call wrap_exec*()
if !PSEUDO_RELOADED
@@ -49,7 +49,19 @@ libpseudo execution flow:
pseudo_dropenv()
real_*()
- ... normal function wrappers ...
+ ... normal function wrappers ... (templates/wrapfuncs.c):
+ pseudo_check_wrappers() || !real_*
+ return enosys
+ variadic setup (if necessary)
+ if pseudo_disabled return real_*()
+ pseudo_sigblock
+ pseudo_getlock
+ if antimagic rc = real_*()
+ else rc = wrap_*()
+ variadic end (if necessary)
+ pseudo_droplock
+ unmask signals
+ return rc
pseudo execution flow:
pseudo.c: main()
diff --git a/guts/clone.c b/guts/clone.c
index 8299c54..b3400c7 100644
--- a/guts/clone.c
+++ b/guts/clone.c
@@ -12,21 +12,15 @@
* 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_reinit_libpseudo();
- } else {
- pseudo_setupenv();
- pseudo_dropenv();
- }
- /* call the real syscall */
- rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid);
+ if (!pseudo_get_value("PSEUDO_RELOADED")) {
+ pseudo_setupenv();
+ pseudo_reinit_libpseudo();
} else {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("clone");
+ pseudo_setupenv();
+ pseudo_dropenv();
}
-
+ /* call the real syscall */
+ rc = (*real_clone)(fn, child_stack, flags, arg, pid, tls, ctid);
/* ...
* return rc;
* }
diff --git a/guts/fork.c b/guts/fork.c
index b7fd239..76cac6f 100644
--- a/guts/fork.c
+++ b/guts/fork.c
@@ -6,23 +6,18 @@
* wrap_fork(void) {
* int rc = -1;
*/
- if (real_fork) {
- rc = real_fork();
- /* special case: we may want to enable or disable
- * pseudo in the child process
- */
- if (rc == 0) {
- if (!pseudo_get_value("PSEUDO_RELOADED")) {
- pseudo_setupenv();
- pseudo_reinit_libpseudo();
- } else {
- pseudo_setupenv();
- pseudo_dropenv();
- }
+ rc = real_fork();
+ /* special case: we may want to enable or disable
+ * pseudo in the child process
+ */
+ if (rc == 0) {
+ if (!pseudo_get_value("PSEUDO_RELOADED")) {
+ pseudo_setupenv();
+ pseudo_reinit_libpseudo();
+ } else {
+ pseudo_setupenv();
+ pseudo_dropenv();
}
- } else {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("fork");
}
/* return rc;
* }
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 414cc05..470206a 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -252,6 +252,12 @@ execl(const char *file, const char *arg, ...) {
int rc = -1;
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execl");
+ return rc;
+ }
+
va_start(ap, arg);
argv = execl_to_v(ap, arg, 0);
va_end(ap);
@@ -267,29 +273,20 @@ execl(const char *file, const char *arg, ...) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execv(file, argv);
+ int save_errno;
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execl\n");
- errno = save_errno;
- free(argv);
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execl\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execl");
- free(argv);
- return rc;
- }
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execv(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execl\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
}
int
@@ -300,6 +297,12 @@ execlp(const char *file, const char *arg, ...) {
int rc = -1;
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execlp");
+ return rc;
+ }
+
va_start(ap, arg);
argv = execl_to_v(ap, arg, 0);
va_end(ap);
@@ -315,29 +318,20 @@ execlp(const char *file, const char *arg, ...) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execvp(file, argv);
+ int save_errno;
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execlp\n");
- errno = save_errno;
- free(argv);
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execlp\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execlp");
- free(argv);
- return rc;
- }
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execvp(file, argv);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execlp\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
}
int
@@ -349,6 +343,12 @@ execle(const char *file, const char *arg, ...) {
int rc = -1;
+ if (!pseudo_check_wrappers()) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execle");
+ return rc;
+ }
+
va_start(ap, arg);
argv = execl_to_v(ap, arg, (char *const **)&envp);
va_end(ap);
@@ -364,29 +364,20 @@ execle(const char *file, const char *arg, ...) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execve(file, argv, envp);
+ int save_errno;
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execle\n");
- errno = save_errno;
- free(argv);
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execle\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execle");
- free(argv);
- return rc;
- }
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execve(file, argv, envp);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execle\n");
+ errno = save_errno;
+ free(argv);
+ return rc;
}
int
@@ -395,6 +386,12 @@ execv(const char *file, char *const *argv) {
int rc = -1;
+ if (!pseudo_check_wrappers() || !real_execv) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execv");
+ return rc;
+ }
+
pseudo_debug(4, "called: execv\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
@@ -402,28 +399,19 @@ execv(const char *file, char *const *argv) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
+
+ int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execv(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execv\n");
- errno = save_errno;
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execv\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execv");
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execv(file, argv);
- return rc;
- }
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execv\n");
+ errno = save_errno;
+ return rc;
}
int
@@ -432,6 +420,12 @@ execve(const char *file, char *const *argv, char *const *envp) {
int rc = -1;
+ if (!pseudo_check_wrappers() || !real_execve) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execve");
+ return rc;
+ }
+
pseudo_debug(4, "called: execve\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
@@ -439,28 +433,19 @@ execve(const char *file, char *const *argv, char *const *envp) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
+
+ int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execve(file, argv, envp);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execve\n");
- errno = save_errno;
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execve\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execve");
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execve(file, argv, envp);
- return rc;
- }
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execve\n");
+ errno = save_errno;
+ return rc;
}
int
@@ -469,6 +454,12 @@ execvp(const char *file, char *const *argv) {
int rc = -1;
+ if (!pseudo_check_wrappers() || !real_execvp) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("execvp");
+ return rc;
+ }
+
pseudo_debug(4, "called: execvp\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
@@ -476,28 +467,19 @@ execvp(const char *file, char *const *argv) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
+
+ int save_errno;
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- rc = wrap_execvp(file, argv);
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execvp\n");
- errno = save_errno;
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execvp\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("execvp");
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_execvp(file, argv);
- return rc;
- }
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: execvp\n");
+ errno = save_errno;
+ return rc;
}
int
@@ -506,6 +488,12 @@ fork(void) {
int rc = -1;
+ if (!pseudo_check_wrappers() || !real_fork) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("fork");
+ return rc;
+ }
+
pseudo_debug(4, "called: fork\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
@@ -513,27 +501,18 @@ fork(void) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
+
+ int save_errno;
- rc = wrap_fork();
+ rc = wrap_fork();
- save_errno = errno;
-
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: fork\n");
- errno = save_errno;
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: fork\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("fork");
+ save_errno = errno;
- return rc;
- }
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: fork\n");
+ errno = save_errno;
+ return rc;
}
int
@@ -554,6 +533,12 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
int rc = -1;
+ if (!pseudo_check_wrappers() || !real_clone) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("clone");
+ return rc;
+ }
+
va_start(ap, arg);
pid = va_arg(ap, pid_t *);
tls = va_arg(ap, struct user_desc *);
@@ -567,47 +552,40 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
sigprocmask(SIG_SETMASK, &saved, NULL);
return -1;
}
- if (pseudo_check_wrappers()) {
- int save_errno;
- int save_disabled = pseudo_disabled;
- /* 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!
- */
+
+ int save_errno;
+ int save_disabled = pseudo_disabled;
+ /* 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!
+ */
#include "guts/clone.c"
- if (save_disabled != pseudo_disabled) {
- if (pseudo_disabled) {
- pseudo_disabled = 0;
- pseudo_magic();
- } else {
- pseudo_disabled = 1;
- pseudo_antimagic();
- }
+ if (save_disabled != pseudo_disabled) {
+ if (pseudo_disabled) {
+ pseudo_disabled = 0;
+ pseudo_magic();
+ } else {
+ pseudo_disabled = 1;
+ pseudo_antimagic();
}
-
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: clone\n");
- errno = save_errno;
- return rc;
- } else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: clone\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("clone");
-
- return rc;
}
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: clone\n");
+ errno = save_errno;
+ return rc;
}
+#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_execv)(const char *file, char *const *argv) = NULL;
static int (*real_execve)(const char *file, char *const *argv, char *const *envp) = NULL;
static int (*real_execvp)(const char *file, char *const *argv) = NULL;
diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c
index 61065c5..0a90efd 100644
--- a/templates/wrapfuncs.c
+++ b/templates/wrapfuncs.c
@@ -21,8 +21,20 @@ ${name}(${decl_args}) {
${variadic_decl}
${rc_decl}
+ if (!pseudo_check_wrappers() || !real_$name) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("${name}");
+ ${rc_return}
+ }
+
${variadic_start}
+ if (pseudo_disabled) {
+ ${rc_assign} (*real_${name})(${call_args});
+ ${variadic_end}
+ ${rc_return}
+ }
+
pseudo_debug(4, "called: ${name}\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
@@ -30,39 +42,25 @@ ${name}(${decl_args}) {
sigprocmask(SIG_SETMASK, &saved, NULL);
${def_return}
}
- if (pseudo_check_wrappers()) {
- int save_errno;
- if (antimagic > 0) {
- if (real_$name) {
- /* call the real syscall */
- ${rc_assign} (*real_${name})(${call_args});
- } else {
- /* rc was initialized to the "failure" value */
- pseudo_enosys("${name}");
- }
- } else {
- ${alloc_paths}
- /* exec*() use this to restore the sig mask */
- pseudo_saved_sigmask = saved;
- ${rc_assign} wrap_$name(${call_args});
- ${free_paths}
- }
- ${variadic_end}
- save_errno = errno;
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: $name\n");
- errno = save_errno;
- ${rc_return}
+
+ int save_errno;
+ if (antimagic > 0) {
+ /* call the real syscall */
+ ${rc_assign} (*real_${name})(${call_args});
} else {
- pseudo_droplock();
- sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: $name\n");
- /* rc was initialized to the "failure" value */
- pseudo_enosys("${name}");
- ${variadic_end}
- ${rc_return}
+ ${alloc_paths}
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ ${rc_assign} wrap_$name(${call_args});
+ ${free_paths}
}
+ ${variadic_end}
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(4, "completed: $name\n");
+ errno = save_errno;
+ ${rc_return}
}
static ${type}