str_list_push: remove unused function
[oweals/opkg-lede.git] / libopkg / xsystem.c
index 06d6ae4fa1c0b6a586756f8acffe175f6a70d17a..b8ada59d25dbdd196181dbaa68a575b05749d6e6 100644 (file)
    General Public License for more details.
 */
 
-#include "opkg.h"
+#include <sys/types.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 #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
    Otherwise, the 8-bit return value of the program ala WEXITSTATUS
    as defined in <sys/wait.h>.
 */
-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:
+               opkg_perror(ERROR, "%s: vfork", 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) {
+               opkg_perror(ERROR, "%s: waitpid", 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)) {
+               opkg_msg(ERROR, "%s: Child killed by signal %d.\n",
+                        argv[0], WTERMSIG(status));
+               return -1;
+       }
 
-    if (WIFEXITED(err)) {
-       /* Normal child exit */
-       return WEXITSTATUS(err);
-    }
+       if (!WIFEXITED(status)) {
+               /* shouldn't happen */
+               opkg_msg(ERROR, "%s: Your system is broken: got status %d "
+                        "from waitpid.\n", argv[0], status);
+               return -1;
+       }
 
-    fprintf(stderr, "%s: ERROR: Received unintelligible return value from system: %d",
-           __FUNCTION__, err);
-    return -1;
+       return WEXITSTATUS(status);
 }
-