execv, ждать, Unix программирование, Как дождаться ребенка

Привет, я работаю над оболочкой unix и столкнулся с двумя проблемами. Мне было интересно, может ли кто-нибудь из вас помочь мне. Моя первая проблема заключается в том, что оболочка не ждет завершения дочернего процесса. На самом деле я могу ввести больше команд, пока работает дочерний процесс. Моя вторая проблема заключается в следующих двух строках. Я не получаю никакого отображения на оболочке.

    fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
    fprintf(stderr, "Child pid = %d\n", pid);

У меня есть следующий метод для выполнения процесса, введенного пользователем: например, firefox, ls -a и т. д.

void execute(char *command[], char *file, int descriptor){
    pid_t pid;
    pid = fork();

    if(pid == -1){
        printf("error in execute has occurred\n");
    }
    if(pid == 0){           
        execvp(*command,command);
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", pid);
        wait(&status);
            exit(EXIT_SUCCESS);
    }
    else{
        printf("ignore for now\n");
    }
}

Здесь я вызываю команду выполнения. Он отлично работает и запускает процесс, но не ждет его завершения.

 execute(commandArgv, "STANDARD",0);

Ребята, у вас есть идеи, что я могу делать неправильно? Спасибо, я очень ценю любое время, которое вы тратите, чтобы помочь мне в этом.


person user69514    schedule 23.09.2009    source источник
comment
я перешел ждать после вызова выполнения. это работало нормально. благодарю вас.   -  person user69514    schedule 23.09.2009
comment
Или переместите его в игнорируемую на данный момент часть кода, что родитель выполняет после того, как дочерний элемент был fork()'d.   -  person Stéphane    schedule 23.09.2009


Ответы (3)


После запуска execvp() он никогда не вернется. Он заменяет в памяти работающее приложение тем, что было предоставлено. Так что ваши fprintf() и wait() находятся не в том месте.

person Stéphane    schedule 23.09.2009
comment
Перечитывая ваш вопрос... возможно, все, что вам нужно, это вызов system() для запуска вашей команды? Или вы специально хотите fork+execvp? - person Stéphane; 23.09.2009

Помимо правильной проработки фактической логики (предложения Стефана все хороши), вы также можете захотеть fflush(stderr) после fprintf-ing, чтобы ваши сообщения об ошибках сразу выводились, а не буферизировались.

person pbr    schedule 24.09.2009

У вас небольшая ошибка в том, как работает процесс. После вызова execvp пути назад уже нет. fork() дает вам родительский и идентичный дочерний, но execvp перезаписывает дочернее изображение, чтобы оно было командой, которую вы вызываете.

Execvp возвращает только при возникновении серьезных ошибок, препятствующих перезаписи образа. Итак, вам нужно распечатать вещи до его вызова. Таким образом, вы также можете изменить EXIT_SUCCESS на EXIT_FAILURE.

Теперь есть еще одна ошибка с использованием wait: вы всегда хотите, чтобы родитель ждал ребенка, а не наоборот. Нельзя просить ребенка подождать. Ей нечего ждать, она побежит и кончится. Итак, вам нужно переместить вызов wait() в часть else.

void execute(char *command[], char *file, int descriptor)
{
    pid_t pid;
    pid = fork();

    if(pid == -1)
    {
        printf("fork() error in execute() has occurred\n");
        return; /* return here without running the next else statement*/
    }
    if(pid == 0)
    {           
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", getpid());
        execvp(*command,command);
        fprintf(stderr, "Error! Can't overwrite child's image!\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Parent waiting for child pid: %d\n", pid);
        wait(&status);
        printf("Parent running again\n");
    }
}

Но, читая ваш вопрос, возможно, вы действительно не хотите, чтобы родитель ждал. Если это так, просто не используйте функцию wait().

Береги себя, Беко.

Отредактировано: небольшие ошибки. pid дочернего элемента — getpid()

person DrBeco    schedule 08.04.2011