tomyamaのブログ

日記・雑記。

C言語 signal() ANSI C シグナル操作

C言語の「signal()関数」のサンプルプログラムです。

 

 

 

  • signal() シグナル操作
    • 準拠 ANSI C, C89, C99, POSIX.1-2001.
    • #include <signal.h>
    • sighandler_t signal (int signum, sighandler_t sighandler) ;
    • シグナル signum の処理方法を handler に設定する。handler には、
      SIG_IGN, SIG_DFL, プログラマが定義した関数「シグナル・ハンドラ」のアドレスのいずれかを指定する。
      【シグナル・ハンドラ】
      typedef void( *sighandler_t )( int );

目次


ソースコード

[signal.c]

#include <stdio.h>
#include <errno.h>          /* errno */
#include <string.h>         /* strerror() */
#include <signal.h>         /* signal() */
#include <stdlib.h>         /* exit(), abort(), atexit() */


/*+++++++[ 変数型定義 ]+++++++++++++++++++++++++++++++++++*/
/*+++++++[ 構造体定義 ]+++++++++++++++++++++++++++++++++++*/
/*+++++++[ 関数プロトタイプ ]+++++++++++++++++++++++++++++*/

void exit_ex( void );
void sighdl_abort( int signum );


/*+++++++[ 変数定義 ]+++++++++++++++++++++++++++++++++++++*/
/*+++++++[ 関数定義 ]+++++++++++++++++++++++++++++++++++++*/

/*************************************************
 * プログラムのエントリポイント
 *************************************************/

int main( int argc, char *argv[] )
{

    /* プロセスの正常終了時に呼び出される関数を登録 */
    if( atexit( exit_ex ) != 0 ){
        fprintf( stderr, "%s(): error: atexit(): <%d>%s\n",
            __FUNCTION__, errno, strerror (errno)) ;
        return errno;
    }

    /* SIGABRTシグナルを受信した時の動作を変更する */
    if( signal( SIGABRT, sighdl_abort ) == SIG_ERR ){
        fprintf( stderr, "%s(): error: signal(): <%d>%s\n",
            __FUNCTION__, errno, strerror( errno ) );
        return errno;
    }

    /*  */
    if( argc == 2 )         /* 引数が1つ指定されてたら */
        abort();
    else if( argc >= 3 )    /* 引数が2つ以上指定されてたら */
        exit( EXIT_FAILURE );

    printf( "%s(): normal end\n", __FUNCTION__ );
    return EXIT_SUCCESS;
}


/*************************************************
 * 正常終了時に呼び出される関数
 *************************************************/

void exit_ex( void )
{
    printf( "%s(): normal end\n", __FUNCTION__ );
    return;
}


/*************************************************
 * シグナルハンドラ << SIGABRT >>
 *************************************************/

void sighdl_abort( int signum )
{
    printf( "%s(): abnormal end: abort !!!\n", __FUNCTION__ );
    return;
}

 

実行例

Cygwin 3.3.6-1, gcc (GCC) 11.3.0

$ gcc -Wall -O2 -o signal_cygwin signal.c
$
$ ./signal_cygwin.exe     ; echo "command_exit_status: $?"
main(): normal end
exit_ex(): normal end
command_exit_status: 0
$
$ ./signal_cygwin.exe 1   ; echo "command_exit_status: $?"
sighdl_abort(): abnormal end: abort !!!
Aborted
command_exit_status: 134
$
$ ./signal_cygwin.exe 1 2 ; echo "command_exit_status: $?"
exit_ex(): normal end
command_exit_status: 1
$

 

CentOS Stream 9, gcc (GCC) 11.3.1

$ gcc -Wall -O2 -o signal_centos9 signal.c
$ ## 実行結果はCygwinと同じ

 

Windows 10, Visual Studio 2022, x86 Native Tools Command Prompt for VS 2022

>cl /nologo /utf-8 /Fe:signal_msvc.exe signal.c
signal.c

>signal_msvc.exe     & echo command_exit_status: %ERRORLEVEL%
main(): normal end
exit_ex(): normal end
command_exit_status: 0

>signal_msvc.exe 1   & echo command_exit_status: %ERRORLEVEL%
sighdl_abort(): abnormal end: abort !!!
command_exit_status: 0

>signal_msvc.exe 1 2 & echo command_exit_status: %ERRORLEVEL%
exit_ex(): normal end
command_exit_status: -1073740791

>