it-swarm.com.ru

Как получить возвращаемое значение программы, запущенной через вызов члена семейства функций exec?

Я знаю, что можно прочитать команды вывода с трубы? Но как насчет получения возвращаемого значения? Например, я хочу выполнить:

execl("/bin/ping", "/bin/ping" , "-c", "1", "-t", "1", ip_addr, NULL);

Как я могу получить возвращенное значение команды ping, чтобы узнать, вернул ли он 0 или 1?

12
skujins

Вот пример, который я написал давным-давно. По сути, после того, как вы разветвляете дочерний процесс и wait его статус выхода, вы проверяете статус с помощью двух макросов. WIFEXITED используется для проверки, нормально ли завершился процесс, а WEXITSTATUS проверяет, что вернуло число, если оно вернулось нормально:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int number, statval;
    printf("%d: I'm the parent !\n", getpid());
    if(fork() == 0)
    {
        number = 10;
        printf("PID %d: exiting with number %d\n", getpid(), number);
        exit(number) ;
    }
    else
    {
        printf("PID %d: waiting for child\n", getpid());
        wait(&statval);
        if(WIFEXITED(statval))
            printf("Child's exit code %d\n", WEXITSTATUS(statval));
        else
            printf("Child did not terminate with exit\n");
    }
    return 0;
}
12
AraK

Вы можете использовать waitpid, чтобы получить статус выхода вашего дочернего процесса как:

int childExitStatus;
waitpid( pID, &childExitStatus, 0); // where pID is the process ID of the child.
5
codaddict

функция exec familly не возвращает, возвращаемое значение int присутствует только тогда, когда во время запуска возникает ошибка (например, не найден файл для exec).

Вы должны получить возвращаемое значение из сигнала, отправленного процессу, который разветвился перед вызовом exec.

call wait () или waitpid () в вашем обработчике сигналов (ну, вы также можете вызывать wait () в своем процессе, не используя какой-либо обработчик сигналов, если ему больше нечего делать).

4
kriss

Были проблемы с пониманием и применением существующих ответов.

В ответ AraK , если в приложении запущено более одного дочернего процесса, невозможно узнать, какой конкретный дочерний процесс выдал полученный статус выхода. Согласно справочной странице,

wait () и waitpid ()

Системный вызов wait () приостанавливает выполнение вызывающего процесса до тех пор, пока один из его дочерних элементов не завершится . Ожидание вызова (& статус) эквивалентно:

       waitpid(-1, &status, 0);

   The **waitpid()** system call suspends execution of the calling process until a **child specified by pid** argument has changed state.

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

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int number, statval;
    int child_pid;
    printf("%d: I'm the parent !\n", getpid());
    child_pid = fork();
    if(child_pid == -1)
    { 
        printf("could not fork! \n");
        exit( 1 );
    }
    else if(child_pid == 0)
    {
        execl("/bin/ping", "/bin/ping" , "-c", "1", "-t", "1", ip_addr, NULL);
    }
    else
    {
        printf("PID %d: waiting for child\n", getpid());
        waitpid( child_pid, &statval, WUNTRACED
                    #ifdef WCONTINUED       /* Not all implementations support this */
                            | WCONTINUED
                    #endif
                    );
        if(WIFEXITED(statval))
            printf("Child's exit code %d\n", WEXITSTATUS(statval));
        else
            printf("Child did not terminate with exit\n");
    }
    return 0;
}

Не стесняйтесь превратить этот ответ в редактирование ответа АраК.

3
xor007

Вы можете подождать дочерний процесс и получить его статус завершения. Системный вызов wait (pid), попробуйте прочитать об этом.

0
duduamar