표준 유틸리티를 사용하여 bash에서 신호를 잠금 해제하는 방법은 무엇입니까?
지난 몇 주 동안 Macos의 쉘이 중단되는 것을 발견했습니다(예: yes | head
종료되지 않음). 더 깊이 파고들어 내가 만든 모든 새로운 포탄이 상당히 많은 신호 세트를 차단하고 있다는 사실을 발견했습니다. (그래서 이전 예에서는 SIGPIPE가 차단되었습니다. 도구 작성자를 위한 참고 사항, 등 yes
의 반환 값을 확인하세요 write
.)printf
이 동작은 약간 짜증나지만 이제 문제를 알았으므로 쉽게 해결할 수 있습니다. 그러나 그것은 쉽지 않습니다. trap
목적에 부합하지 않는 것 같습니다 (나는 bash를 사용하고 있습니다). 표준 유틸리티를 사용하여 차단된 신호 세트를 지우려면 bash 시작에 무엇을 추가할 수 있습니까? 다음을 추가했는데 매우 혼란스러워 보입니다.
if { ! show-mask && which unblock; } > /dev/null 2>&1; then
exec unblock bash
fi
show-mask 및 unblock은 다음에서 빌드됩니다.
$ cat show-mask.c
/* Show the current set of blocked signals */
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
struct sigaction act = {{0}};
sigset_t old;
if(sigprocmask(SIG_SETMASK, NULL, &old)) {
perror("sigprocmask");
return EXIT_FAILURE;
}
printf("mask: %x\n", old);
return !!old;
}
$ cat unblock.c
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void
set_default(struct sigaction *act, int s)
{
if(sigaction(s, act, NULL)) {
perror("sigaction");
exit(EXIT_FAILURE);
}
}
int
main(int argc, char **argv)
{
struct sigaction act = {{0}};
sigset_t new;
sigemptyset(&new);
if(sigprocmask(SIG_SETMASK, &new, NULL)) {
perror("sigprocmask");
return EXIT_FAILURE;
}
act.sa_handler = SIG_DFL;
set_default(&act, SIGPIPE);
set_default(&act, SIGINT);
set_default(&act, SIGTERM);
execvp(argv[1], argv+1);
perror("execlp");
return EXIT_FAILURE;
}