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 */
xsystem(const char * argv[])33 int xsystem(const char *argv[])
34 {
35 	int status;
36 	pid_t pid;
37 
38 	pid = vfork();
39 
40 	switch (pid) {
41 	case -1:
42 		opkg_perror(ERROR, "%s: vfork", argv[0]);
43 		return -1;
44 	case 0:
45 		/* child */
46 		execvp(argv[0], (char *const *)argv);
47 		_exit(-1);
48 	default:
49 		/* parent */
50 		break;
51 	}
52 
53 	if (waitpid(pid, &status, 0) == -1) {
54 		opkg_perror(ERROR, "%s: waitpid", argv[0]);
55 		return -1;
56 	}
57 
58 	if (WIFSIGNALED(status)) {
59 		opkg_msg(ERROR, "%s: Child killed by signal %d.\n",
60 			 argv[0], WTERMSIG(status));
61 		return -1;
62 	}
63 
64 	if (!WIFEXITED(status)) {
65 		/* shouldn't happen */
66 		opkg_msg(ERROR, "%s: Your system is broken: got status %d "
67 			 "from waitpid.\n", argv[0], status);
68 		return -1;
69 	}
70 
71 	return WEXITSTATUS(status);
72 }
73