From 603bec779ab8f0751bc48b0394aadd261fafdcde Mon Sep 17 00:00:00 2001 From: graham.gower Date: Mon, 16 Nov 2009 19:17:55 -0500 Subject: Use vfork()/execvp() instead of system(). Parts based on a patch by Mike Westerhof for OpenEmbedded. git-svn-id: http://opkg.googlecode.com/svn/trunk@320 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- (limited to 'libopkg/xsystem.c') diff --git a/libopkg/xsystem.c b/libopkg/xsystem.c index 267f2f9..123510f 100644 --- a/libopkg/xsystem.c +++ b/libopkg/xsystem.c @@ -19,12 +19,7 @@ #include #include "xsystem.h" - -/* XXX: FEATURE: I shouldn't actually use system(3) at all. I don't - really need the /bin/sh invocation which takes resources and - introduces security problems. I should switch all of this to a sort - of execl() or execv() interface/implementation. -*/ +#include "libbb/libbb.h" /* Like system(3), but with error messages printed if the fork fails or if the child process dies due to an uncaught signal. Also, the @@ -34,31 +29,44 @@ Otherwise, the 8-bit return value of the program ala WEXITSTATUS as defined in . */ -int xsystem(const char *cmd) +int +xsystem(const char *argv[]) { - int err; + int status; + pid_t pid; + + pid = vfork(); - err = system(cmd); + switch (pid) { + case -1: + perror_msg("%s: %s: vfork", __FUNCTION__, argv[0]); + return -1; + case 0: + /* child */ + execvp(argv[0], (char*const*)argv); + _exit(-1); + default: + /* parent */ + break; + } - if (err == -1) { - fprintf(stderr, "%s: ERROR: fork failed before execution: `%s'\n", - __FUNCTION__, cmd); - return -1; - } + if (waitpid(pid, &status, 0) == -1) { + perror_msg("%s: %s: waitpid", __FUNCTION__, argv[0]); + return -1; + } - if (WIFSIGNALED(err)) { - fprintf(stderr, "%s: ERROR: Child process died due to signal %d: `%s'\n", - __FUNCTION__, WTERMSIG(err), cmd); - return -1; - } + if (WIFSIGNALED(status)) { + error_msg("%s: %s: Child killed by signal %d\n", + __FUNCTION__, argv[0], WTERMSIG(status)); + return -1; + } - if (WIFEXITED(err)) { - /* Normal child exit */ - return WEXITSTATUS(err); - } + if (!WIFEXITED(status)) { + /* shouldn't happen */ + error_msg("%s: %s: Your system is broken: got status %d " + "from waitpid\n", __FUNCTION__, argv[0], status); + return -1; + } - fprintf(stderr, "%s: ERROR: Received unintelligible return value from system: %d", - __FUNCTION__, err); - return -1; + return WEXITSTATUS(status); } - -- cgit v0.9.1