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

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.