programing

C에서 Ctrl+C를 잡다

javaba 2022. 8. 7. 17:47
반응형

C에서 Ctrl+C를 잡다

C에서 +는 어떻게 C잡습니까?

신호 핸들러로.

.bool used에 main():

#include <signal.h>

static volatile int keepRunning = 1;

void intHandler(int dummy) {
    keepRunning = 0;
}

// ...

int main(void) {

   signal(SIGINT, intHandler);

   while (keepRunning) { 
      // ...

2017년 6월 편집:특히 이 답변을 편집하고 싶은 충동을 가진 분들에게. 답은 7년 전에 썼어네, 언어 기준이 바뀝니다.만약 당신이 정말 세상을 개선해야 한다면, 당신의 새로운 대답을 추가해 주세요. 하지만 제 대답은 그대로 두세요.정답에 제 이름이 적혀있기 때문에 제 말도 들어있었으면 좋겠어요.감사합니다.

@Peter Varo는 Dirk의 답변을 갱신했지만 Dirk는 변경을 거부했다.피터의 새로운 답변은 다음과 같습니다.

위의 스니펫은 올바른 예이지만 가능하면 최신 표준에서 제공하는 최신 유형과 보증을 사용해야 합니다.따라서 에 준거한 구현을 원하는 사용자를 위한 보다 안전하고 현대적인 대안을 제시합니다.

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

static volatile sig_atomic_t keep_running = 1;

static void sig_handler(int _)
{
    (void)_;
    keep_running = 0;
}

int main(void)
{
    signal(SIGINT, sig_handler);

    while (keep_running)
        puts("Still running...");

    puts("Stopped by signal `SIGINT'");
    return EXIT_SUCCESS;
}

C11 Standard: 7.14⁄2 헤더<signal.h>자를선선선선sig_atomic_t이는 비동기 인터럽트가 존재하는 경우에도 원자 엔티티로서 액세스 할 수 있는 오브젝트의 정수 타입(volatile-qualified)

더 나아가:

C11 표준: 7.14.1.1µ5 신호가 호출된 결과 이외의 경우abort ★★★★★★★★★★★★★★★★★」raise가 "Signal Handler"가 "Signal Handler"를 가진 되지 않습니다.static로하는 것 이외에는 잠금 volatile sig_atomic_t

여기를 체크해 주세요.

주의: 이것은 핸들러의 셋업 방법을 설명하는 간단한 예이지만, 다른 것을 어기지 않기 위해 항상 지켜야 할 규칙이 있습니다.아래 댓글을 읽어주세요.

위의 샘플 코드:

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

void     INThandler(int);

int  main(void)
{
     signal(SIGINT, INThandler);
     while (1)
          pause();
     return 0;
}

void  INThandler(int sig)
{
     char  c;

     signal(sig, SIG_IGN);
     printf("OUCH, did you hit Ctrl-C?\n"
            "Do you really want to quit? [y/n] ");
     c = getchar();
     if (c == 'y' || c == 'Y')
          exit(0);
     else
          signal(SIGINT, INThandler);
     getchar(); // Get new line character
}

UN*X 플랫폼에 관한 부록.

★★★★★★에 의하면signal(2), GNU/Linux의 man , " "signalsigaction:

signal()의 동작은 UNIX 버전에 따라 다르며 Linux 버전에 따라 역사적으로도 다릅니다.사용을 피합니다.대신 sigaction(2)을 사용합니다.

System V에서는 시스템은 신호의 추가 인스턴스 전달을 차단하지 않았습니다.신호를 전달하면 핸들러가 기본 인스턴스로 리셋됩니다.BSD에서는 시멘틱스가 변경되었습니다.

Dirk Eddelbuettel의 이전 답변의 다음 변형은 다음과 같습니다.sigaction대신signal:

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

static bool keepRunning = true;

void intHandler(int) {
    keepRunning = false;
}

int main(int argc, char *argv[]) {
    struct sigaction act;
    act.sa_handler = intHandler;
    sigaction(SIGINT, &act, NULL);

    while (keepRunning) {
        // main loop
    }
}

또는 다음과 같이 단말기를 raw 모드로 할 수 있습니다.

struct termios term;

term.c_iflag |= IGNBRK;
term.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
term.c_lflag &= ~(ICANON | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSANOW, &term);

이제 읽기 +C 키 입력이 가능해질 것입니다.fgetc(stdin)단,Z 평소처럼 +,Q +,S + 등 사용할 수 없기 때문에 주의해 주십시오.

기존 응답에 대해서는 신호 처리는 플랫폼에 따라 다릅니다.예를 들어 Win32는 POSIX 운영체제보다 훨씬 적은 수의 신호를 처리합니다.여기를 참조하십시오.Win32에서는 SIGINT가 signals.h로 선언되어 있습니다만, 이 설명서에 기재되어 있는 주에서는 기대했던 대로 동작하지 않는 것을 설명하고 있습니다.

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR)
  printf("\ncan't catch SIGINT\n");
  // A long long wait so that we can easily issue a signal to this process
  while(1) 
    sleep(1);
  return 0;
}

sig_handler 함수는 전달된 인수의 값이 SIGINT와 동일한지 확인한 후 printf가 실행됩니다.

트랩을 설정합니다(1개의 핸들러로 여러 신호를 트랩할 수 있습니다).

신호(SIGQUIT, my_handler);
신호(SIGINT, my_handler);

신호를 원하는 대로 처리하되 제한사항과 변경사항에 유의하십시오.

void my_void (int sig){/* 여기 코드가 있습니다.*/}

종료 전에 인쇄만 하면 됩니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void sigint_handler(int);

int  main(void)
{
    signal(SIGINT, sigint_handler);

     while (1){
         pause();   
     }         
    return 0;
}

 void sigint_handler(int sig)
{
    /*do something*/
    printf("killing process %d\n",getpid());
    exit(0);
}

언급URL : https://stackoverflow.com/questions/4217037/catch-ctrl-c-in-c

반응형