signal() - 割り込みの処理

標準

標準/拡張機能 C/C++ 依存項目

ISO C
POSIX.1
POSIX.4a
XPG4
XPG4.2
C99
Single UNIX Specification、バージョン 3

両方  

形式

#include <signal.h>

void(*signal(int sig, void(*func)(int)))(int);

機能説明

プロセスが、オペレーティング・システム、または raise() 関数からの 割り込みシグナル sig を処理するいくつかの方法のうち 1 つを 選択できるようになります。

sig 引数は、signal.h ヘッダー・ファイルで定義される マクロの 1 つであることが必要です。表 1 を参照してください。

func 引数は 、signal.h ヘッダー・ファイル、または 関数アドレスで定義されるマクロ、SIG_DFL または SIG_IGN の 1 つであることが必要です。

func の値が SIG_DFL の場合には、そのシグナル のデフォルト処理が行われます。func の値 が SIG_IGN の場合には、シグナルは無視されます。そうでない 場合には、そのシグナルが起こったときに、func で 呼び出される関数が示されます。このような関数は 、シグナル・ハンドラー と呼ばれます。

シグナルが 起こったときに、func で関数が示されると、次のような ことになります。
  1. まず、signal(sig,SIG_DFL); の等値が実行される か、またはシステムのインプリメンテーション定義ブロッキングが 実行されます (sig の値が SIGILL の場合には 、SIG_DFL へのリセットの出現は、定義済みインプリメンテーション です)。
  2. 次に、(*func)(sig); の等値が実行されます。関数 func は、return ステートメントを 実行するか、または abort()、exit()、または longjmp() 関数 を呼び出すことによって終了できます。func により戻りステートメントが実行され、さらに sig の 値が SIGFPE または計算例外に対応するその他の インプリメンテーション定義値である場合、その動作は未定義です。そうでない場合には、プログラムは実行が割り込まれた点から再開されます。

abort() または raise() 関数の呼び出し以外の理由でシグナルが起こる場合、シグナル・ハンドラーにより (ハンドラーを起動させるシグナルに対応する、シグナル番号の最初の引数で)、signal() 関数そのもの以外の標準ライブラリーの関数が呼び出される場合、その動作は未定義です。また、型 volatile sig_atomic_t の静的ストレージ期間変数に値を割り当てる以外のことによって、静的ストレージ期間のオブジェクトがシグナル・ハンドラーで参照される場合の動作も、未定義です。さらに、signal() 関数へのこのような呼び出しで SIG_ERR が戻されると、errno の値があいまいになります。

プログラム開始処理で、signal(sig, SIG_IGN); の 等値は一部の選択シグナルで実行される場合があります。signal(sig, SIG_DFL); の等値は、その他のすべてのシグナルで実行されます。

割り込みシグナルが受信されたときに取られる処置は、func の 値によって異なります。
意味
SIG_DFL
シグナルのデフォルト処理が行われます。
SIG_IGN
シグナルが無視されます。
Language Environment リリース 3 では、SIGUSR1、SIGUSR2、SIGINT、および SIGTERM のデフォルトは、無視されるシグナルから異常終了へと変更されます。この変更を補正するには、以下のような呼び出しシーケンスを 介して、シグナルが無視されることを明示的に登録する ことができます。
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGINT,  SIG_IGN);
signal(SIGTERM, SIG_IGN);

これらの呼び出しはソースで行うか、または再リンクが 必要な HLL ユーザー出口 CEEBINT から行うことができます。

POSIX の特殊な動作: POSIX(ON) を実行する z/OS®UNIX C アプリケーションでは、割り込みシグナルが、kill() や別のプロセスからも発生する場合があります。 プログラムでは sigaction() を使用して、シグナル・ハンドラーを明確化できます。シグナル・ハンドラーに制御がある間、sigaction() で シグナルがブロックされます。signal() を使用してシグナル・ハンドラーを明確化すると、シグナルでデフォルト・アクションが逆に戻されます。このタイプの次のシグナルの制御を得るためにシグナル・ハンドラー が必要な場合には、signal() を再発行する必要があります。

signal(sigfunc)sigaction(sig&actNULL) と等しく、ここでは act は、func の sa_action を 含む sigaction 構造体、sigemptyset() による sa_mask、および _SA_OLD_STYLE を含む sa_flags が指されています。

注: sigaction() 関数は signal() インターフェースに代わるものであり、優先的に使用する必要があります。特に、sigaction() と signal() を同じプロセスで使用し、同じシグナルを制御することはできません。

非同期シグナルをサポートするシグナル・キャッチング関数 のコーディングの考慮事項については、sigaction() - シグナル・アクションの検査/変更を 参照してください。

sig 引数は、signal.h ヘッダー・ファイルで定義される マクロの 1 つであることが必要です。

C++ の特殊な動作:
  • シグナル処理と C++ 例外処理が混在している場合は、動作は未定義です。また、コンストラクターおよびデストラクターでのシグナル処理の使用も未定義です。
  • C++ と C 言語のリンケージ規約には互換性がありません。したがって、signal() は、C++ 関数ポインターを受け取ることができません。C++ 関数ポインターを signal() へ渡そうとすると、コンパイラーがエラーのフラグを付けます。したがって、C++ 言語で signal() 関数を使用するには、確立されたシグナル・ハンドラー・ルーチンを extern "C" と宣言することによって、必ずこれらのルーチンに C リンケージが含まれるようにしなければなりません。

サポートされるシグナルのリストを次に示します。

表 1. C/C++ でサポートされるシグナル - POSIX(OFF)
デフォルト・アクション 意味
SIGABND 1 異常終了
SIGABRT 1 異常終了 (abort() によって送信)
SIGFPE 1 オーバーフロー、ゼロによる割り算、および誤った演算などの、マスクされない算術例外
SIGILL 1 誤った関数イメージの検出
SIGINT 1 対話式アテンション
SIGSEGV 1 メモリーへの誤ったアクセス
SIGTERM 1 プログラムへ送信された終了要求
SIGUSR1 1 ユーザー・アプリケーションによる使用目的
SIGUSR2 1 ユーザー・アプリケーションによる使用目的
SIGIOERR 2 重大な入出力エラーが検出された。
表 1デフォルト・アクションは、以下のとおりです。
1
プロセスの正常終了。
2
シグナルの無視。

ランタイム・オプション POSIX(ON) が指定されているとき、 プログラム・チェックもしくは ABEND の結果、シグナル SIGABND、SIGFPE、 SIGILL、または SIGSEGV のシグナル・キャッチャーが起動して、そのシグナル・キャッチャー が RETURN ステートメントを実行すると、プロセスは終了します。

戻り値

正常に実行された場合には、signal() は、最新の func の値を戻します。

失敗した場合は、signal() は SIG_ERR の値を 戻して、errno に正数を設定します。

設定される errno 値はありません。 エラーが起こった場合には、errno 値を使用して perror() を発行してください。

CELEBS20
⁄* CELEBS20                                      

   This example shows you how to establish a signal handler.                    

 *⁄                                                                             
#include <signal.h>                                                             
#include <stdio.h>                                                              
#include <stdlib.h>                                                             
#define  ONE_K  1024                                                            
                                                                                
#define OUT_OF_STORAGE       (SIGUSR1)                                          
                                                                                
⁄* The SIGNAL macro does a signal() checking the return code *⁄                 
#define SIGNAL(handler, StrCln)       {                ¥                        
  if (signal((handler), (StrCln)) == SIG_ERR) {        ¥                        
    perror("Could not signal user signal");            ¥                        
    abort();                                           ¥
  }                                                    ¥
}                                                                               
                                                                                
#ifdef __cplusplus                 ⁄* the __cplusplus macro       *⁄            
extern "C" void StrCln(int);       ⁄* is automatically defined    *⁄            
#else                              ⁄* by the C++⁄MVS compiler     *⁄            
void StrCln(int);                                                               
#endif                                                                          
                                                                                
void DoWork(char **, int);                                                      
                                                                                
int main(int argc, char *argv[]) {                                              
  int size;                                                                     
  char *buffer;                                                                 
                                                                                
  signal(OUT_OF_STORAGE, StrCln);                                               
                                                                                
  if (argc != 2) {                                                              
    printf("Syntax: %s size ¥n", argv[0]);                                      
    return(-1);                                                                 
  }                                                                             
                                                                                
  size = atoi(argv[1]);                                                         
                                                                                
  DoWork(&buffer, size);                                                        
  return(0);                                                                    
}                                                                               
                                                                                
void StrCln(int SIG_TYPE) {                                                     
  printf("Failed trying to malloc storage¥n");                                  
  signal(SIG_TYPE, SIG_DFL);                                                    
  exit(0);                                                                      
}                                                                               
                                                                                
void DoWork(char **buffer, int size) {                                          
  int rc;                                                                       
                                                                                
  while (*buffer !=NULL)                                                        
    *buffer = (char *)malloc(size*ONE_K);                                       
  if (*buffer == NULL) {                                                        
     if (raise(OUT_OF_STORAGE)) {                                               
        perror("Could not raise user signal");                                  
        abort();                                                                
     }                                                                          
  }                                                                             
  return;                                                                       
}                                                                               

関連情報