web-dev-qa-db-ja.com

Cでの信号処理

CでCtrl-CおよびCtrl-Dの信号処理を実装するにはどうすればよいですか。押すと、プログラムが終了します...

私のプログラムは次のとおりです:

int main(){
 char msg[400];

 while(1){
   printf("Enter: ");
   fgets(msg,400,stdin);
   printf("%s\n",msg); 
 }
}

おかげで、

デイブ

21
Dave

POSIXシグナルを処理する場合、2つの手段を自由に使用できます。まず、簡単な(しかし非推奨の)方法 signal() です。第二に、より洗練された、現在の複雑な方法 sigaction() です。作業が必要な一部のプラットフォームで利用できない場合を除き、sigaction()を使用してください。

この章 glibcマニュアルの==は、2つの違いを説明し、両方を使用する方法の良いサンプルコードを提供します。また、処理可能な信号の一覧を示し、それらの処理方法の処理方法を推奨し、特定の信号がどのように通知されるかをさらに詳しく説明します(またはありません)現在being処理されています。これは、ここで回答に貼り付けたいコードよりもはるかに多いため、リンクになります。

リンクを読んで例を処理するのに1時間か2時間は本当に価値があります。シグナル処理(特にデーモン化するプログラム)は非常に重要です。優れたプログラムは、処理可能なすべての致命的な信号(SIGHUPなど)を処理し、使用していない可能性のある信号(SIGUSR1/SIGUSR2など)を明示的に無視する必要があります。

また、少なくともカーネルが前者をマージし、後者をマージする方法を理解するまでは、通常の信号とリアルタイム信号の違いを研究しても支障はありません。

一度作業を終えたら、信号を処理するために簡単に変更できる関数のセットを作成し、そのコードを何度も繰り返し使用する傾向があります。

差し迫ったニーズを解決する方法を示すために迅速で汚いコードスニペットを提供しないことを申し訳ありませんが、これは迅速で汚いトピックではありません:)

33
Tim Post

まず、Ctrl + DはEOFインジケーターであり、トラップすることはできません。プログラムが入力を待っているときにCtrl + Dを押すと、ファイルの終わりを示し、それ以上の入力は期待できません。 、Ctrl + Cを使用してプログラムを終了します。これはSIGINTであり、次のようにしてトラップできます。

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv){
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    // do the work
    exit(0);
}

void init_signals(void){
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if (sig == SIGINT) panic("Caught signal for Ctrl+C\n");
}

void panic(const char *fmt, ...){
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

void cleanup(void){
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}
14
t0mm13b

あなたの例では、CTRL-Cハンドリンドはまったく必要ないようです。アプリケーションが他のソースからのSIGINTを処理する必要がない限り、「signal(SIGINT、SIG_IGN)」で十分です。 CTRL-Dは通常、信号を生成せず、EOF条件を通信するだけです。一般に、端末の動作を制御できます(コンソール入力について話していますが、そうではありませんか?) termiosライブラリ (また ここ )を使用します。「割り込み」文字(CTRL-C)、EOF 1つおよび他の多くのもの(XON、XOFF、モデム制御...)

よろしく

2

これはCtrl + cを押したときにシグナルを処理するためのプログラムです

シグナル関数の構文は次のとおりです:signal(signal name, function name);

#include<stdio.h>
#include<signal.h>  // for handling signal 

void signal_handler() 
{
    printf("Signal Handled here\n");
}

main() 
{
    printf("In main function..\n");

    // SIGINT is signal name create  when Ctrl+c will pressed 
    signal(SIGINT,signal_handler);  

    sleep(15);

    printf("In main after called from signal_handle \n");

}
2
RUSHIKESH KARDE
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
void signal_catch()
{
    printf("hi,Your signal catched Here");  
}
int main()
{
    signal(SIGINT,signal_catch);
//press ctrl+c
    sleep(10);
    return 0;
}//end main

//if you want to simply ignore ctrl+c interrupt use following code in main

int main()
{
    signal(SIGINT,SIG_IGN);
    sleep(100);
    return 0;
}//end main  
//this program  wont accept ctrl+c interrupt for 100 seconds. 
0
Sherlock