signal handler를 중복해서 등록 했는데 정상적으로 처리가 됩니다. 이유가 궁금합니다. 소스첨부.
글쓴이: sia79 / 작성시간: 화, 2008/10/21 - 4:42오후
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)
Forums:


glibc-2.3 의 sigaction()
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
댓글 달기