signal handler를 중복해서 등록 했는데 정상적으로 처리가 됩니다. 이유가 궁금합니다. 소스첨부.

sia79의 이미지

sigaction의 구조체를 보고,

 struct sigaction {
        void (*sa_handler)(int);
        void (*sa_sigaction)(int, siginfo_t *, void *);
        sigset_t sa_mask;
        int sa_flags;
        void (*sa_restorer)(void);
 }

일부로 아래와 같은 오류 코드를 만든 것이었는데, 이게 정상적으로 실행되어 놀랍고, 이유가 궁금합니다.

#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
 
void sig_int(int signo);
void sig_usr(int signo);
 
int main()
{
    int i = 0;
    struct sigaction intsig;
 
    sigemptyset(&intsig.sa_mask);
 
    intsig.sa_flags = 0;
 
    intsig.sa_handler = sig_int;
 
    // SIGINT
    if (sigaction(SIGINT, &intsig, 0) == -1)
    {
        printf ("signal(SIGINT) error");
        return -1;
    }
 
    intsig.sa_handler = sig_usr;
 
    // SIGUSR2
    if (sigaction(SIGUSR2, &intsig, 0) == -1)
    {
        printf ("signal(SIGUSR2) error");
        return -1;
    }
 
    while(1)
    {
        printf("%d\n", i);
        i++;
        sleep(1);
    }
}
 
void sig_int(int signo)
{
    printf("SIGINT !!!!\n");
    sleep(1);
}
 
void sig_usr(int signo)
{
    printf("sig_usr2\n");
    sleep(1);
}

sigaction intsig의 sig_handler 변수에 여러 함수를 대입하면 가장 마지막에 대입된 함수만 실행 될 것이라고 예상하고,

예상한 대로라면 sigint 시그널을 날리나 sigusr2 시그널을 날리나 같은 결과가 나올 것이라고 생각했습니다.

이게 어찌 된 것인가요?

Fedora 5 OS, gcc version 4.1.0 20060304 (Red Hat 4.1.0-3)

bushi의 이미지

glibc-2.3 의 sigaction() 구현은 대략 다음과 같습니다.

int
__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
{
   struct kernel_sigaction kact, koact;
 
   ...
 
   if (act) {
          kact.k_sa_handler = act->sa_handler;
          kact.sa_flags = act->sa_flags;
          memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
          ...
 
   }
   ...
   result = INLINE_SYSCALL (rt_sigaction, 4,
                               sig, act ? __ptrvalue (&kact) : NULL,
                               oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
   ...
}

memcpy() 한 놈으로 호출하는군요.
다른 OS 에선 틀릴 수도 있고, glibc 버전에 따라 달라질 수도 있으니 사파의 초식은 삼가는 편이...

OTL