cli: implement --force-signature
[oweals/opkg-lede.git] / libopkg / xsystem.c
1 /* xsystem.c - system(3) with error messages
2
3    Carl D. Worth
4
5    Copyright (C) 2001 University of Southern California
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2, or (at
10    your option) any later version.
11
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 */
17
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21
22 #include "xsystem.h"
23 #include "libbb/libbb.h"
24
25 /* Like system(3), but with error messages printed if the fork fails
26    or if the child process dies due to an uncaught signal. Also, the
27    return value is a bit simpler:
28
29    -1 if there was any problem
30    Otherwise, the 8-bit return value of the program ala WEXITSTATUS
31    as defined in <sys/wait.h>.
32 */
33 int
34 xsystem(const char *argv[])
35 {
36         int status;
37         pid_t pid;
38
39         pid = vfork();
40
41         switch (pid) {
42         case -1:
43                 opkg_perror(ERROR, "%s: vfork", argv[0]);
44                 return -1;
45         case 0:
46                 /* child */
47                 execvp(argv[0], (char*const*)argv);
48                 _exit(-1);
49         default:
50                 /* parent */
51                 break;
52         }
53
54         if (waitpid(pid, &status, 0) == -1) {
55                 opkg_perror(ERROR, "%s: waitpid", argv[0]);
56                 return -1;
57         }
58
59         if (WIFSIGNALED(status)) {
60                 opkg_msg(ERROR, "%s: Child killed by signal %d.\n",
61                         argv[0], WTERMSIG(status));
62                 return -1;
63         }
64
65         if (!WIFEXITED(status)) {
66                 /* shouldn't happen */
67                 opkg_msg(ERROR, "%s: Your system is broken: got status %d "
68                         "from waitpid.\n", argv[0], status);
69                 return -1;
70         }
71
72         return WEXITSTATUS(status);
73 }