forkpty()에 의해 시작된 Bash 쉘은 SIGINT를 무시하는 하위 프로세스를 생성합니다. SIGINT가 무시되지 않도록 하는 이유와 방법은 무엇입니까?

forkpty()에 의해 시작된 Bash 쉘은 SIGINT를 무시하는 하위 프로세스를 생성합니다. SIGINT가 무시되지 않도록 하는 이유와 방법은 무엇입니까?

bash 쉘을 실행하기 위해 forkpty를 사용하는 C 프로그램이 있습니다. 나는 이 쉘에 의해 시작된 프로그램이 시작할 때 SIGINT를 무시한다는 것을 발견했습니다. 그래서 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 쉘에서 시작된 프로세스의 상태를 볼 때마다 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 쉘에 보낼 때 bash 쉘이 SIGINT를 무시하지 않기 때문에 작동한다는 것입니다.

답변1

아마도 다음을 수행해야 할 수도 있습니다.

stty sane

나는 알아차렸다forkpty() man페이지에 termios 설정을 복사할 것이라고 나와 있습니다.*termp새로 열린 pty에 대한 것이지만 이를 처리하는 방법을 지정하지 않으며, NULL이 아닌 유일한 인수는 forkpty()pty 마스터 fd에 대한 것입니다. 내 생각엔 완전히 빈 termios 구조로 끝날 것 같은데, 이는 별로 유용하지 않습니다. 별로 문제가 되지 않을 것입니다 . 자체 터미널 작업을 모두 처리 bash해야 하므로 어쨌든 기본적으로 모든 기본 문자를 해석하게 됩니다.readline()

이것은 유익한 블록 인용문에서 나온 것입니다.기사이 주제에 대해:

stty-F옵션은 다른 프로그램이 터미널에서 무엇을 하고 있는지 확인하는 데 유용합니다. tty쉘에서 실행 하면 해당 쉘의 터미널 장치 경로가 인쇄됩니다./dev/pts/N( 적어도 Linux에서는 일반적인 형식 ). 이제 다른 셸에서 실행하여 stty -a -F /dev/pts/N첫 번째 셸의 터미널이 어떻게 구성되어 있는지 확인할 수 있습니다. 그런 다음 첫 번째 셸에서 프로그램을 실행하고 stty두 번째 셸에서 주문을 반복하여 어떤 설정이 설정되어 있는지 확인할 수 있습니다. 예를 들어, stty -F /dev/pts/10지금 실행 하면( bash그 pty를 통해 누군가와 대화할 때)gnome-terminal, 이해합니다:

    $ stty -F /dev/pts/10
      speed 38400 baud; line = 0;
      eol = M-^?; eol2 = M-^?; swtch = M-^?; lnext = <undef>; min = 1; time = 0;
     -icrnl iutf8
     -icanon -echo

bash/readline그러면 비활성화 된 것을 확인할 수 있습니다.CR→LF번역 입력( icrnl), 장애를 입히다canonical모드와echo, 그러나 UTF-8 모드가 활성화되었습니다( bashutf-8 로케일이 감지되었기 때문에). stty해당 셸에서 직접 실행 하면 약간 다른 내용이 표시됩니다.

     $ stty
       speed 38400 baud; line = 0;
       eol = M-^?; eol2 = M-^?; swtch = M-^?;
       iutf8

bash자체 설정을 유지하기 termios때문 입니다.(을 위한 readline)을 실행하고 프로그램을 실행할 때의 설정이 프롬프트에 입력할 때의 설정과 다르도록 실행 중인 프로그램에 대한 설정을 저장하고 복원합니다 bash.

답변2

이 결과는 귀하의 질문에 표시된 코드 블록으로 인한 것이 아닐 것입니다. 전체 설정의 다른 부분에는 다른 것이 있어야 합니다.

설명하는 사용 시나리오를 고려해 볼 때 가장 가능성이 높은 이유는 실제로 코드 어딘가에 SIGINT 무시를 설정했기 때문입니다.앞으로포크 또는앞으로포크티 어린이를 실행합니다.

이는 귀하가 설명하는 결과를 생성할 것입니다. 왜냐하면 귀하의 forkpty'ed는 bash -iSIGINT가 무시된 설정을 상속하고 자체 내부 목적을 위해 다른 상태로 설정하기 때문입니다(그래서 SIGINT를 무시하지 않음). 또한 상속된 상태로 재설정됩니다. 생성되는 모든 명령에 대해 상태를 무시합니다.

이것은 Bash의 동작에 대한 문서입니다. Bash 매뉴얼 페이지의 "명령 실행 환경" 장, 특히 다음 단락을 참조하십시오.

내장 함수나 쉘 함수가 아닌 단순 명령을 실행하고자 하는 경우에는 다음과 같이 구성된 별도의 실행 환경에서 호출된다. [...]

[...]

o 쉘이 포착한 트랩은 쉘의 부모로부터 상속된 값으로 재설정되고 쉘이 무시한 트랩은 무시됩니다.

화타이

관련 정보