我有一个使用forkpty来执行bash shell的C程序。我发现这个shell启动的程序是在忽略SIGINT的情况下启动的,所以当我向shell发送一个Ctrl-C时,它们永远不会关闭。
示例:
int masterFd;
char* args[] = {"/bin/bash", "-i", NULL };
int procId = forkpty(&masterFd, NULL, NULL, NULL);
if( procId == 0 ){
execve( args[0], args, NULL);
}
else {
// Simple code that reads from standard in and writes to masterFd.
// I also register for Ctrl-C and write it to masterFd if caught
}
其他控制字符似乎可以通过,ctrl-D,ctrl-?但是,每当我查看新bash shell启动的进程的状态时,就会看起来SIGINT被屏蔽掉了。
MyShell:# sleep 1000
StandardTerm:# ps -ef | grep sleep
root 26611 19278 0 17:44 pts/1 00:00:00 sleep 1000
root 26613 32376 0 17:44 pts/1 00:00:00 grep sleep
StandardTerm:# grep Sig proc/26611/status
SigQ: 0/256428
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000010006 <- THE 6 IS THE PROBLEM
SigCgt: 0000000180000000
SigIgn具有2位设置,这意味着忽略2(SIGINT)。如果我做同样的事情,但在标准终端中运行睡眠(或猫一个巨大的文件或其他),这个位被清除。当我启动我的pty bash导致它创建忽略SIGINT的孙子程序时,我在做什么?
此外,如果我向进程发送SIGINT信号
StandardTerm:# kill -2 26611
没有任何反应。奇怪的是,当我向bash shell发送相同的命令时,我运用了它,因为bash shell不会忽略SIGINT。
提前致谢!
答案 0 :(得分:0)
父进程是否已屏蔽SIGINT
?
fork()
和execve()
都将信号掩码传播到子procs,也许就是这种情况?
答案 1 :(得分:0)
查看 termios(3)手册页。您使用&#39; NULL &#39;作为 forkpty 调用中的 termios (第三个)参数,意味着&#39; c_iflag &#39; termios 结构值将是未定义的,并且继承其父进程的值。 (谢谢你@ djc6535)
pid_t forkpty(int *amaster, char *name,
const struct termios *termp,
const struct winsize *winp);
struct termios
{
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
来自 termios(3)手册页:
c_iflag flag constants:
IGNBRK Ignore BREAK condition on input.
BRKINT If IGNBRK is set, a BREAK is ignored. If it is not set but BRKINT is set, then a BREAK causes the input and output
queues to be flushed, and if the terminal is the controlling terminal of a foreground process group, it will cause a SIG‐
INT to be sent to this foreground process group. When neither IGNBRK nor BRKINT are set, a BREAK reads as a null byte
('\0'), except when PARMRK is set, in which case it reads as the sequence \377 \0 \0.
相关部分是&#39; 当既没有设置IGNBRK也没有设置BRKINT时,BREAK读取为空字节(&#39; \ 0&#39;)
所以一切都按预期工作。
也许建立一个 termios 结构来设置各种重要的标志?