/* Same as 'command', but passing an argv. */ int commandvf (char **stdoutput, char **stderror, int flags, char const *const *argv) { int r; r = commandrvf (stdoutput, stderror, flags, (void *) argv); if (r == 0) return 0; else return -1; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_e2fsck (const char *device, int correct, int forceall) { const char *argv[MAX_ARGS]; CLEANUP_FREE char *err = NULL; size_t i = 0; int r; /* Default if not selected. */ if (!(optargs_bitmask & GUESTFS_E2FSCK_CORRECT_BITMASK)) correct = 0; if (!(optargs_bitmask & GUESTFS_E2FSCK_FORCEALL_BITMASK)) forceall = 0; if (correct && forceall) { reply_with_error ("only one of the options 'correct', 'forceall' may be specified"); return -1; } ADD_ARG (argv, i, str_e2fsck); ADD_ARG (argv, i, "-f"); if (correct) ADD_ARG (argv, i, "-p"); if (forceall) ADD_ARG (argv, i, "-y"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandrvf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR, argv); /* 0 = no errors, 1 = errors corrected. * * >= 4 means uncorrected or other errors. * * 2, 3 means errors were corrected and we require a reboot. This is * a difficult corner case. */ if (r == -1 || r >= 2) { reply_with_error ("%s", err); return -1; } return 0; }
/* Same as 'command', but we allow the status code from the * subcommand to be non-zero, and return that status code. * We still return -1 if there was some other error. */ int commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...) { va_list args; const char **argv; char *s; int i, r; /* Collect the command line arguments into an array. */ i = 2; argv = malloc (sizeof (char *) * i); if (argv == NULL) { perror ("malloc"); return -1; } argv[0] = (char *) name; argv[1] = NULL; va_start (args, name); while ((s = va_arg (args, char *)) != NULL) { const char **p = realloc (argv, sizeof (char *) * (++i)); if (p == NULL) { perror ("realloc"); free (argv); va_end (args); return -1; } argv = p; argv[i-2] = s; argv[i-1] = NULL; } va_end (args); r = commandrvf (stdoutput, stderror, flags, argv); /* NB: Mustn't free the strings which are on the stack. */ free (argv); return r; }
/** * Same as C<command>, but we allow the status code from the * subcommand to be non-zero, and return that status code. * * We still return C<-1> if there was some other error. * * There is also a macro C<commandr(out,err,name,...)> which calls * C<commandrf> with C<flags=0>. */ int commandrf (char **stdoutput, char **stderror, unsigned flags, const char *name, ...) { va_list args; CLEANUP_FREE const char **argv = NULL; char *s; int i, r; /* Collect the command line arguments into an array. */ i = 2; argv = malloc (sizeof (char *) * i); if (argv == NULL) { perror ("malloc"); return -1; } argv[0] = (char *) name; argv[1] = NULL; va_start (args, name); while ((s = va_arg (args, char *)) != NULL) { const char **p = realloc (argv, sizeof (char *) * (++i)); if (p == NULL) { perror ("realloc"); va_end (args); return -1; } argv = p; argv[i-2] = s; argv[i-1] = NULL; } va_end (args); r = commandrvf (stdoutput, stderror, flags, argv); return r; }