솔라리스에서의 시그널 함수에 대해

ddoman의 이미지

동작 환경은 솔라리스 8 sparc 입니다.

아래 코드의 간단한 tcp server를 만들었습니다.

void sig_chld( int signo )
{
        pid_t pid;
        int stat;

        while( ( pid = waitpid( -1, &stat, WNOHANG ) ) > 0 )
         printf( "child %d terminated\n", pid );
;
//      signal( SIGCHLD, sig_chld );
        return;
}

int main( int argc, char* argv[] )
{
        int listenfd, connfd;
        pid_t childpid;
        socklen_t clilen;
        struct sockaddr_in cliaddr, servaddr;

        listenfd = socket( AF_INET, SOCK_STREAM, 0 );
        bzero( &servaddr, sizeof( servaddr ) );

        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
        servaddr.sin_port = htons( 9978 );

        bind( listenfd, (struct sockaddr*)&servaddr, sizeof( servaddr ) );

        listen( listenfd, 1024 );

        signal( SIGCHLD, sig_chld );

        for( ; ; )
        {
                clilen = sizeof( cliaddr );
                connfd = accept( listenfd, (struct sockaddr*)&cliaddr, &clilen );

                if( (childpid = fork()) == 0 )
                {
                        close( listenfd );
                        printf( "connected from client!\n" );
                        exit(0);
                }
                close( connfd );
        }
}

다음은 클라이언트..

int main( int argc, char* argv[] )
{
        int sockfd;
        struct sockaddr_in servaddr;

        if( argc != 2 )
        {
                printf( "usage : client IP_ADDR\n" );
                exit(0);
        }

        sockfd = socket( AF_INET, SOCK_STREAM, 0 );
        bzero( &servaddr, sizeof( servaddr ) );
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons( 9978 );
        inet_pton( AF_INET, argv[1], &servaddr.sin_addr );

        connect( sockfd, (struct sockaddr*)&servaddr, sizeof( servaddr ) );
}

평범한 tcp server/client 예제입니다만,
이상하게 sigchild signal이 정상적으로 오지않습니다.

server를 띄어놓고 client로 접속을 하면
첫번째 연결로 생성된 child process는 죽으면서 sig_chld핸들러가
실행이 됩니다만,
두번째 연결부터는 child가 죽더라도 sig_child 핸들러가 실행이
안되면서 좀비프로세스로 남습니다.

마치 한번 시그널 핸들러가 불리고 시그널 핸들러설정이 풀리는거 같아
sig_chld함수안에서 다시 signal( SIGCHLD, sig_chld );
를 호출 해주면 의도한대로 계속 계속 시그널이 잘 옵니다.(주석처리한부분)

리눅스에서 같은 코드로 컴파일하면
굳이 signal함수를 핸들러안에서 다시 호출해주지 않아도
계속 계속 잘 옵니다만, 솔라리스 8에서는 안되는 이유가 뭔가요?

아시는분 계시면 조언 부탁드립니다.

hb_kim의 이미지

유닉스 계열에 따라 조금 동작의 차이가 있기는 한데, 이미 해보신바와 같이 주석 처리하신 부분을 다시 되살리시는것이 정답입니다.

Quote:
"In non-BSD environments the signal handler for any signal is often set back to SIG_DFL just before the signal handler is called. In order to respond to more than one instance of a signal in these environments another call to signal() must be made EACH time the signal is received. The logical place for that repeated call is inside the handler itself as the last operation"
bugiii의 이미지

sigaction도 한번 고려해 보심이...

zwolf의 이미지

signal 대신에 sigset 함수를 사용하셔야 될 것 같네요.

솔라리스는 특이하게 signal 함수는 시그널 처리 후, 다시 디폴트 핸들러로 다시 복귀시킵니다.

리눅스에서 같은 동작을 원하시면 sigset 함수를 쓰셔야 합니다.

아니면 sigaction 함수를 사용하셔서...

---------------------------------
< ACK and you shall receive. >

< ACK and you shall receive. >

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.