Это моя программа popen_test.cpp
:
int main(int argc, char* argv[])
{
signal(SIGCHLD, SIG_IGN);
sigset_t sset;
sigaddset(&sset, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &sset, &sset);
char command[128] = {0};
snprintf(command, sizeof(command), "python popen_test.py");
FILE* file;
file = popen(command, "r");
if ( !file )
{
printf("command: %s is error\n", command);
return -1;
}
char result[256]={0};
int len = fread(result, sizeof(char), 256, file);
printf("result is :%s\n", result);
int ret = pclose(file);
if (ret == -1)
{
printf("pclose error:%d, errno:%d, str_err:%s\n", ret, errno, strerror(errno));
return -1;
}
}
Скрипт
import os
import signal
import subprocess
if __name__ == "__main__":
test = signal.getsignal(signal.SIGCHLD)
if test == signal.SIG_DFL:
print "sig_dfl"
if test == signal.SIG_IGN:
print "sig_ign"
print test
POPEN открывает дочерний процесс; дочерний процесс вызывает exec
для запуска python popen_test.py
, я знаю, когда вызывается exec
, сигнал SIGCHLD (если установлен на SIG_IGN) может быть сброшен или не установлен на SIG_DFL. Почему результат sig_dfl, а не sig_ign?
Вы не sigprocmask()
ограничители для аргументов sigprocmask()
. Ваш компилятор должен жаловаться на использование одного и того же аргумента дважды.
Спецификация POSIX для документов execv()
:
Сигналы, установленные для действия по умолчанию (SIG_DFL) в изображении вызывающего процесса, должны быть установлены в действие по умолчанию в новом образе процесса. За исключением SIGCHLD, сигналы, которые должны игнорироваться (SIG_IGN) изображением вызывающего процесса, должны быть проигнорированы новым образцом процесса.
Если сигнал SIGCHLD установлен на игнорирование обращением вызывающего процесса, неясно, будет ли сигнал SIGCHLD установлен на игнорирование или на действие по умолчанию в новом образе процесса.
Комментарии OP:
Но "Расширенное программирование в среде UNIX" говорит, что если сигнал SIGXXX игнорируется образами вызывающего процесса, в новом процессе сигнал также игнорируется?
Разница заключается в том, что APUE имеет дело с UNIX; UNIX на самом деле не POSIX (хотя оба близки). POSIX говорит, что платформа может быть совместима с POSIX и все еще перезагружать SIGCHLD
до SIG_DFL
даже если это был SIG_IGN
в исходном процессе. Ваш код показывает, что ваша платформа - это то, почему POSIX предоставляет исключение для SIGCHLD
.
Из любопытства, какую платформу вы используете?
restrict
квалификаторы для аргументовsigprocmask()
. Ваш компилятор должен жаловаться на использование одного и того же аргумента дважды. Обратите внимание, чтоexecv()
документирует, что если сигнал SIGCHLD настроен на игнорирование образом вызывающего процесса, то не определено, установлен ли сигнал SIGCHLD на игнорирование или на действие по умолчанию в новом образе процесса. О чем вы озадачены?