Help us understand the problem. What is going on with this article?

Cで強制終了を回避(出来るだけ)

More than 3 years have passed since last update.

はじめに

概要

ユーザの操作によってCプログラムが終了してしまうのを(可能な限り)回避する方法をCソースで解説します。
この記事を参考にすると例えばCプログラムを実行中にCtrl+Cを押下した際でも
終了することなく動作し続けるプログラムが作れます。

目的

以下の用途に使える(かもしれない)。

仕組み

通常、Terminal上でプログラムが動作している際にCtrl + Cを押下すると、
対象プログラムのプロセスにSIGINTシグナル(プロセスを管理するための信号的なもの)が配送されます。
SIGINTシグナルを受け取ったプログラムはOSによって処理が強制終了されます。

今回はシグナル処理設定をCプログラム上で変更し、
SIGINTシグナルを受け取っても終了しないようにOSにお願いする(無視してもらう)感じで
強制終了を回避します。

シグナルの種類

シグナルはSIGINTだけではなく様々なシグナルが存在します。
強制終了に関係しそうな一部を以下に示します。

シグナル 概要 どうやって配送?
SIGINT キーボードからの割り込み Ctrl + C 押下
SIGQUIT キーボードによる中止 Ctrl + '\'またはCtrl + '4'押下
SIGTSTP 端末(tty)から入力された一旦停止 Ctrl + Z押下
SIGTERM 終了 (コマンド) kill pid
SIGKILL 強制終了 (コマンド) kill -KILL pid
SIGSTOP 一時停止 (コマンド) kill -s SIGSTOP pid

他にもSIGPWR(電源喪失)などがあったりします。
詳しくはこちらを参考ください。

シグナル処理の変更(上書き)

(途中)
先ほど挙げたシグナルを受け取った際の動作を無視する事が可能です。
例えばSIGINTを受け取った際の処理を無視するには以下のようになります。

signal()よりもsigaction()を使った方が良いみたいです。参考程度に。。

ign_sigint.c
    // Ctrl + C を無視
    sig = signal( SIGINT , SIG_IGN );
    if( SIG_ERR == sig ){
        exit(-1);
    }

強制終了回避(出来るだけ)

signal()またはsigaction()を使用しても、
SIGKILL(強制終了)とSIGSTOP(一時停止)に関しては無視できないみたいです。
とりあえず出来るだけ無視してみたコードは以下になります。

signal()よりもsigaction()を使った方が良いみたいです。参考程度に。。

sigchg.c
#define _GNU_SOURCE      // sighandler_tを使用する為に定義
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main( void ){
  sighandler_t sig = 0;

  // Ctrl + C を無視
  sig = signal( SIGINT , SIG_IGN );
  if( SIG_ERR == sig ){
    exit(-1);
  }
  // kill pidを無視
  sig = signal( SIGTERM , SIG_IGN );
  if( SIG_ERR == sig ){
    exit(-1);
  }
  // Ctrl + '\'を無視
  sig = signal( SIGQUIT , SIG_IGN );
  if( SIG_ERR == sig ){
    exit(-1);
  }
  // Ctrl + Zを無視
  sig = signal( SIGTSTP , SIG_IGN );
  if( SIG_ERR == sig ){
    exit(-1);
  }
  while(1){
    pause();
  }
  return 0;
}

別ターミナルからは終了できてしまいますが、
プログラムを起動したターミナル側では動き続けるようになるはずです。
以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away