2014-11-26 6 views
3

설정 (OSX 10.9.5 (13F34)) 다음과 같은 간단한 프로그램 :OS X 용은 sigaction 잘못 맥북에 sa_mask

#include <stdio.h> 
#include <signal.h> 

static void nop(int unused) { } 

int 
main(void) { 
    struct sigaction sa, osa; 
    sigset_t mask; 

    sigemptyset(&sa.sa_mask); 
    printf("Errno after sigempty sa_mask: %d\n", errno); 
    sigemptyset(&osa.sa_mask); 
    printf("Errno after sigempty oldsa_mask: %d\n", errno); 
    sa.sa_flags = 0; 
    sa.sa_handler = nop; 

    sigprocmask(0, NULL, &mask); 
    printf("Errno after sigprocmask mask: %d\n", errno); 
    printf("%d\n", sigismember(&mask, SIGALRM)); 

    sigaction(SIGALRM, &sa, &osa); 
    printf("Errno after sigaction sa osa: %d\n", errno); 
    printf("%d\n", sigismember(&osa.sa_mask, SIGALRM)); 
    printf("%d\n", sigismember(&sa.sa_mask, SIGALRM)); 

    return 0; 
} 

는 불가사의 인쇄 :

Errno after sigempty sa_mask: 0 
Errno after sigempty oldsa_mask: 0 
Errno after sigprocmask mask: 0 
0 
Errno after sigaction sa osa: 0 
1 
0 

내가 기대 그 sa_mask 멤버 osa의 값이 sigprocmaskmask과 일치해야합니다.

POSIX는이 필드에 대한 요구 사항을 지정합니까? 맨페이지에있는 유일한 언급은 차단할 수없는 신호와 관련하여 그 값이 지정되지 않은 SIGKILL과 같은 것입니다.

리눅스에

,이 프로그램의 인쇄는 :

Errno after sigempty sa_mask: 0 
Errno after sigempty oldsa_mask: 0 
Errno after sigprocmask mask: 0 
0 
Errno after sigaction sa osa: 0 
0 
0 

예상대로.

GCC 버전은 다음과 같습니다

$ gcc --version 
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn) 
Target: x86_64-apple-darw 

진은에 링크되어

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1) 
+0

OS X에서 사용중인 라이브러리 (및 버전)는 무엇입니까? 'errno'는 각각'sig * '호출 후에 어떤 것을 말합니까? –

+0

@BlueMoon이 질문에 대답하기 위해 질문을 업데이트했습니다. – Dave

답변

7

내가 sigprocmask에 의해 주어진 osasa_mask 회원이 mask에 맞게 것으로 기대한다.

예상 사항이 잘못되었습니다.

the current (as of this writing) official POSIX documentation 링크가 있습니다. 그것을 북마크하십시오! 신호

Here is what that documentation says about sa_mask:

추가 세트 신호 끄는 기능을 실행하는 동안 차단 될 수있다.

osa.sa_maskmask과 일치 할 것으로 기대할 이유가 없습니다. mask은 현재 이며 신호 마스크입니다. osa.sa_maskSIGALRM을 처리하기 위해 osa.sa_handler을 호출하는 동안 적용된추가 신호 마스크입니다.

테스트 케이스에서 osa.sa_handlerSIG_DFL이므로 osa.sa_mask의 내용은 부적합합니다. 내가 아는 한 (간략한 검색 후) POSIX는 테스트 케이스에서와 같이 가장 최근의 exec 이후에 신호에 대한 작업을 설정하지 않았을 때 osa.sa_mask이 무엇이되어야하는지에 대해 아무 것도 말하지 않는다. 시스템이 설치 SIGALRM 핸들러를 호출 할 때

또한, 그것은 (는 핸들러를 설치할 때 또는 SA_NODEFERSA_RESETHAND를 통과하지 않은 경우) 자동으로 신호 SIGALRM 마스크를 포함한다.문서는 상기 링크 인용 :

신호가 sigaction() 설치 신호 끄는 기능에 의해 잡힌

이 새로운 신호 마스크 계산 설치된 신호 끄는 기능의 지속 기간 동안 (또는 호출까지되고 sigprocmask() 또는 sigsuspend()). 이 마스크는 전달되는 신호에 대해 현재 신호 마스크와 sa_mask의 값을 합친 값을 취하고 SA_NODEFER 또는 SA_RESETHAND이 설정되지 않은 경우 전달되는 신호를 포함하여 형성됩니다. sa_mask 리눅스가 포함되지 않는 것을 SIGALRM 0 인 경우 sa_flags 사실을 포함하는지

따라서는 부적합 그리고 OS X 않는 상기 신호의 처리에 아무런 차이가 없다. 그것은 set 인수가 null의 경우에도, sigprocmaskhow 인수에 0 (대신에 정의 된 상수 중 하나의) 전달하는 법적 있다고는 (나에게) 명확하지 않다 그것도

참고. 하지만 그걸 SIG_BLOCK으로 바꾸면 아무런 차이가 없습니다.

+0

이것은 정답이라고 생각합니다. 10.9.5의'libSystemB.dylib' 또는 그보다 나은 소스 코드가 있다면 sigset에 해당 비트를 설정하는 것이 좋습니다. –

+0

동의. 좋은 대답! – Dave