#else
{
int res;
- char *wgetcmd;
- char *wgetopts;
- wgetopts = getenv("OPKG_WGETOPTS");
- sprintf_alloc(&wgetcmd, "wget -q %s%s -O \"%s\" \"%s\"",
- (conf->http_proxy || conf->ftp_proxy) ? "-Y on " : "",
- (wgetopts!=NULL) ? wgetopts : "",
- tmp_file_location, src);
- opkg_message(conf, OPKG_INFO, "Executing: %s\n", wgetcmd);
- res = xsystem(wgetcmd);
- free(wgetcmd);
+ const char *argv[8];
+ int i = 0;
+
+ argv[i++] = "wget";
+ argv[i++] = "-q";
+ if (conf->http_proxy || conf->ftp_proxy) {
+ argv[i++] = "-Y";
+ argv[i++] = "on";
+ }
+ argv[i++] = "-O";
+ argv[i++] = tmp_file_location;
+ argv[i++] = src;
+ argv[i++] = NULL;
+ res = xsystem(argv);
+
if (res) {
opkg_message(conf, OPKG_ERROR, "Failed to download %s, error %d\n", src, res);
free(tmp_file_location);
}
if (strcmp(response, "d") == 0) {
- char *cmd;
-
- free(response);
- /* XXX: BUG rewrite to use exec or busybox's internal diff */
- sprintf_alloc(&cmd, "diff -u %s %s", backup, file_name);
- xsystem(cmd);
- free(cmd);
+ const char *argv[] = {"diff", "-u", backup, file_name, NULL};
+ xsystem(argv);
printf(" [Press ENTER to continue]\n");
response = file_read_line_alloc(stdin);
free(response);
#include <sys/wait.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:
+ 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);
}
-