From 1b74520da749f00025251f1dc82aa7de923b96a6 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Mon, 9 Aug 1999 14:01:48 +0000 Subject: [PATCH] add simple_exec{ve,le} git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@6773 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/roken/roken-common.h | 2 + lib/roken/simple_exec.c | 112 ++++++++++++++++++++++++++++----------- 2 files changed, 84 insertions(+), 30 deletions(-) diff --git a/lib/roken/roken-common.h b/lib/roken/roken-common.h index f9018a207..028f7c700 100644 --- a/lib/roken/roken-common.h +++ b/lib/roken/roken-common.h @@ -213,8 +213,10 @@ SigAction signal(int iSig, SigAction pAction); /* BSD compatible */ #endif #endif +int ROKEN_LIB_FUNCTION simple_execve(const char*, char*const[], char*const[]); int ROKEN_LIB_FUNCTION simple_execvp(const char*, char *const[]); int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...); +int ROKEN_LIB_FUNCTION simple_execle(const char*, ...); void ROKEN_LIB_FUNCTION print_version(const char *); diff --git a/lib/roken/simple_exec.c b/lib/roken/simple_exec.c index d241b9e92..6a3b4d5c2 100644 --- a/lib/roken/simple_exec.c +++ b/lib/roken/simple_exec.c @@ -69,6 +69,24 @@ RCSID("$Id$"); 128- is 128 + signal that killed subprocess */ +static int +check_status(pid_t pid) +{ + while(1) { + int status; + + while(waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + return -3; + if(WIFSTOPPED(status)) + continue; + if(WIFEXITED(status)) + return WEXITSTATUS(status); + if(WIFSIGNALED(status)) + return WTERMSIG(status) + 128; + } +} + int simple_execvp(const char *file, char *const args[]) { @@ -80,45 +98,79 @@ simple_execvp(const char *file, char *const args[]) execvp(file, args); exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC); default: - while(1) { - int status; - - while(waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - return -3; - if(WIFSTOPPED(status)) - continue; - if(WIFEXITED(status)) - return WEXITSTATUS(status); - if(WIFSIGNALED(status)) - return WTERMSIG(status) + 128; - } + return check_status(pid); } } +/* gee, I'd like a execvpe */ +int +simple_execve(const char *file, char *const args[], char *const envp[]) +{ + pid_t pid = fork(); + switch(pid){ + case -1: + return -2; + case 0: + execve(file, args, envp); + exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC); + default: + return check_status(pid); + } +} + +static char ** +collect_args(va_list *ap) +{ + char **argv = NULL; + int argc = 0, i = 0; + do { + if(i == argc) { + /* realloc argv */ + char **tmp = realloc(argv, (argc + 5) * sizeof(*argv)); + if(tmp == NULL) { + errno = ENOMEM; + return NULL; + } + argv = tmp; + argc += 5; + } + argv[i++] = va_arg(*ap, char*); + } while(argv[i - 1] != NULL); + return argv; +} + int simple_execlp(const char *file, ...) { va_list ap; - char **argv = NULL; - int argc, i; + char **argv; + int ret; - argc = i = 0; va_start(ap, file); - do { - if(i == argc) { - char **tmp = realloc(argv, (argc + 5) * sizeof(*argv)); - if(tmp == NULL) { - errno = ENOMEM; - return -1; - } - argv = tmp; - argc += 5; - } - argv[i++] = va_arg(ap, char*); - } while(argv[i - 1] != NULL); + argv = collect_args(&ap); va_end(ap); - i = simple_execvp(file, argv); + if(argv == NULL) + return -1; + ret = simple_execvp(file, argv); free(argv); - return i; + return ret; +} + +int +simple_execle(const char *file, ... /* ,char *const envp[] */) +{ + va_list ap; + char **argv; + char *const* envp; + int ret; + + va_start(ap, file); + argv = collect_args(&ap); + envp = va_arg(ap, char **); + va_end(ap); + if(argv == NULL) + return -1; + ret = simple_execve(file, argv, envp); + free(argv); + return ret; }