Из спецификации POSIX для system()
:
Функция system () игнорирует сигналы SIGINT и SIGQUIT и блокирует сигнал SIGCHLD, ожидая завершения команды.Если это может привести к тому, что приложение пропустит сигнал, который убил бы его, то приложение должно проверить возвращаемое значение из system () и предпринять любое действие, подходящее для приложения, если команда прервана из-за получениясигнала.
Итак, чтобы правильно реагировать на сигналы, необходимо проверить возвращаемое значение system()
.
system () возвращает завершениестатус интерпретатора командного языка в формате, заданном waitpid ()
А документы waitpid()
относятся к документам для wait()
, который инструктирует вас использовать следующие макросы, чтобы выяснить причину выхода из процесса:
- WIFEXITED (stat_val)
Оценивает ненулевое значение, еслистатус был возвращен для дочернего процесса, который нормально завершился. - WEXITSTATUS (stat_val)
Если значение WIFEXITED (stat_val) не равно нулю, этот макрос оценивается как младшие 8 битов status аргумент, что дочерний процесс передан _exit () или exit (), или значение, которое дочерний процесс возвратил из main (). - WIFSIGNALED (stat_val)
Оценивает ненулевое значение, если статус былвозвращается для дочернего процесса, который завершился из-за получения сигнала, который не был перехвачен (см.). - WTERMSIG (stat_val)
Если значение WIFSIGNALED (stat_val) не равно нулю, этот макросвычисляется по номеру сигнала, вызвавшего завершение дочернего процесса. - WIFSTOPPED (stat_val)
Оценивает ненулевое значение, если статус был возвращен для дочернего процесса, который в данный момент остановлен. - WSTOPSIG (stat_val)
Если значение WIFSTOPPED (stat_val) не равно нулю, этот макрос оценивается как номер сигнала, вызвавшего остановку дочернего процесса. - WIFCONTINUED (stat_val)
Оценивает ненулевое значение, если статус был возвращен для дочернего процесса, который продолжился с остановки управления заданием.
Вотпример того, как вы будете использовать эту информацию, без необходимости раскручивать отдельный процесс.Обратите внимание, что вы фактически не получите сигнал в родительском процессе, но вы можете определить сигнал, отправленный дочернему процессу:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
while(1)
{
int result = system("ls 2>&1 1>/dev/null");
if (WIFEXITED(result)) {
printf("Exited normally with status %d\n", WEXITSTATUS(result));
} else if (WIFSIGNALED(result)) {
printf("Exited with signal %d\n", WTERMSIG(result));
exit(1);
} else {
printf("Not sure how we exited.\n");
}
}
return 0;
}
И если вы запустите его, вы получите:
$ ./sys
Exited normally with status 0
Exited normally with status 0
Exited normally with status 0
Exited normally with status 0
Exited normally with status 0
Exited normally with status 0
^CExited with signal 2