注意:这是一个常见问题(不限于wolfram
命令,您不必了解wolfram
)。
我考虑包装wolfram
(CUI计算器,例如python解释器)。没有任何包装,SIGINT
会导致程序暂停计算。
$ /usr/bin/wolfram -noinit
In[1] := While[True, 1] #start infinite loop
#execute `kill -SIGINT` from another shell to send SIGINT
Interrupt> #calculation now interrupted (you can cancel or resume it)
但是,SIGINT
使用包装器会导致wolfram
立即退出。
$ ./wrapper.out
In[1] := While[True, 1] #start infinite loop
#execute `kill -SIGINT` (the target is not the wrapper but the `wolfram` itself)
#`wolfram` exits right away
Caught SIGPIPE. #the wrapper recieves SIGPIPE
包装的完整代码在这里。 (在没有exit(0)
和智能指针的情况下,实际代码编写得更好,但是下面的简化代码仍然会引起问题。)
using namespace std;
#include <iostream>
#include <csignal>
void signal_handler(int signal) {
if (signal == SIGINT) {
cout << "Caught SIGINT.\n";
} else {
cout << "Caught SIGPIPE.\n";
}
exit(0); //not good since destructors aren't called
}
int main(int argc, char **argv) {
//set a signal handler
signal(SIGINT, signal_handler);
signal(SIGPIPE, signal_handler);
FILE *pipe = popen("/usr/bin/wolfram -noinit", "w");
while (true) {
string buf;
getline(cin, buf);
fprintf(pipe, "%s\n", buf.c_str());
fflush(pipe);
}
pclose(pipe);
}
为什么使用包装程序会忽略管道处理的信号处理程序?以及如何保留原始信号处理程序的功能? man 3 popen
没有给我任何提示。