Example #1
0
/*
 * Execute a single command.
 * Return value is a COMMAND_RESULT_* constant, or
 * a value from 0 to 255 to indicate the exit code
 * from the utility.
 */
static int
command_execute(struct i_fn_args *a, struct dfui_progress *pr,
		struct command *cmd)
{
	FILE *log = NULL;
	char *filename;
	int cancelled = 0, done = 0, report_done = 0;

	if (cmd->desc != NULL)
		dfui_info_set_short_desc(dfui_progress_get_info(pr), cmd->desc);
	else
		dfui_info_set_short_desc(dfui_progress_get_info(pr), cmd->cmdline);

	if (!dfui_be_progress_update(a->c, pr, &cancelled))
		  abort_backend();

	while (!done) {
		asprintf(&filename, "%sinstall.log", a->tmp);
		log = fopen(filename, "a");
		free(filename);

		if (cmd->log_mode != COMMAND_LOG_SILENT)
			i_log(a, ",-<<< Executing `%s'", cmd->cmdline);
		cmd->result = pipe_loop(a, pr, cmd, &cancelled);
		if (cmd->log_mode != COMMAND_LOG_SILENT)
			i_log(a, "`->>> Exit status: %d\n", cmd->result);

		if (log != NULL)
			fclose(log);

		if (cancelled) {
			if (!dfui_be_progress_end(a->c))
				abort_backend();

			report_done = 0;
			while (!report_done) {
				switch (dfui_be_present_dialog(a->c, "Cancelled",
				    "View Log|Retry|Cancel|Skip",
				    "Execution of the command\n\n%s\n\n"
				    "was cancelled.",
				    cmd->cmdline)) {
				case 1:
					/* View Log */
					view_command_log(a);
					break;
				case 2:
					/* Retry */
					cancelled = 0;
					report_done = 1;
					break;
				case 3:
					/* Cancel */
					cmd->result = COMMAND_RESULT_CANCELLED;
					report_done = 1;
					done = 1;
					break;
				case 4:
					/* Skip */
					cmd->result = COMMAND_RESULT_SKIPPED;
					report_done = 1;
					done = 1;
					break;
				}
			}

			if (!dfui_be_progress_begin(a->c, pr))
				abort_backend();

		} else if (cmd->failure_mode == COMMAND_FAILURE_IGNORE) {
			cmd->result = 0;
			done = 1;
		} else if (cmd->result != 0 && cmd->failure_mode != COMMAND_FAILURE_WARN) {
			if (!dfui_be_progress_end(a->c))
				abort_backend();

			report_done = 0;
			while (!report_done) {
				switch (dfui_be_present_dialog(a->c, "Command Failed!",
				    "View Log|Retry|Cancel|Skip",
				    "Execution of the command\n\n%s\n\n"
				    "FAILED with a return code of %d.",
				    cmd->cmdline, cmd->result)) {
				case 1:
					/* View Log */
					view_command_log(a);
					break;
				case 2:
					/* Retry */
					report_done = 1;
					break;
				case 3:
					/* Cancel */
					/* XXX need a better way to retain actual result */
					cmd->result = COMMAND_RESULT_CANCELLED;
					report_done = 1;
					done = 1;
					break;
				case 4:
					/* Skip */
					/* XXX need a better way to retain actual result */
					cmd->result = COMMAND_RESULT_SKIPPED;
					report_done = 1;
					done = 1;
					break;
				}
			}

			if (!dfui_be_progress_begin(a->c, pr))
				abort_backend();

		} else {
			done = 1;
		}
	}

	return(cmd->result);
}
Example #2
0
int main(int argc, char *argv[]) {
    int procnum = 0;
    int i = 0;
    pid_t pid;

    while (1) {
        int option_index = 0;
        int c;

        c = getopt_long(argc, argv, "d:p:hv",
                        LongOptions, &option_index);

        if (c == EOF)
            break;

        switch(c) {
        case 'v':
            version ();
            break;
        case 'd':
            duration = atoi (optarg);
            break;
        case 'p':
            nproc = atoi (optarg);
            break;
        case '?':
            fprintf (stdout, "invalid usgae\n");
        case 'h':
            usage ();
            break;
        default:
            fprintf (stdout, "Unknown usage %c.\n", c);
            exit (ERR_CMD);
        }
    }

    procnum = nproc / 2;
    while (i < procnum) {
        if ((pid = fork ()) < 0) {
#ifdef DEBUG
            perror ("fork error");
            fprintf (stderr, "%d processes has been created\n");
#endif
            break;
        } 

        if (pid == 0) {
            /* Child process will never return from pipe_loop() */
            return pipe_loop ();
        }

        i++;
    }
#if 1
    /* Should we wait a little more until all the child processes 
     * have been initialized? FIXME*/
    sleep (3);
#endif

#if 0
    /* This would be buggy, especially when huge of child processes
     * are created. It's better to disable this feature
     */

    /* Ok, until now, we can send SIGUSR1 to all the child processes
     * to inform them to begin executed.
     */
    /* Ignore the SIGUSR1 signal */
    signal (SIGUSR1, SIG_IGN);

    if (kill (0, SIGUSR1) == -1) {
#ifdef DEBUG
        perror ("kill error");
#endif
        exit (ERR_SIG);
    }
#endif
    /* wait for termination of all the child process */
    wait_child ();

    /* Calculate the final results and print to the stdout */
    calculate();
    return 0;
} // MAIN