C/Linux

[C] alarm 시그널을 받으면 1초 간격으로 메시지 출력하는 프로그램 구현하기

김호록님 2023. 1. 3. 19:45

wake_up()

  • SIGALRM을 받으면 1초 간격으로 "wake up\n"을 출력하는 프로그램을 작성하시오.
  • SIGALRM 시그널의 핸들러가 실행되는 동안 SIGINT를 제외한 모든 시그널을 블럭하시오.
#define _GNU_SOURCE
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

void mywakeup(int sig) {
  while (1) {
    printf("wake up\n");
    sleep(1);
  }
}

int main(void) {
  int pid, status, signo;
  time_t t;
  sigset_t set;
  static struct sigaction act;
  act.sa_handler = mywakeup;
  sigfillset(&act.sa_mask);
  sigdelset(&act.sa_mask, SIGINT);

  sigaction(SIGALRM, &act, NULL);

  // do not modify
  if ((pid = fork()) < 0) { // error
    perror("fork");
    exit(EXIT_FAILURE);
  } else if (pid == 0) { // child
    // alarm() doesn't work properly on repl.it
    // It is replaced with kill(pid,SIGALRM) in parent part
    // alarm(1);
    pause();
  } else { // parent
    kill(pid, SIGALRM);
    sleep(3);
    kill(pid, SIGINT);

    // wait for child
    if (waitpid(pid, &status, 0) < 0) {
      perror("waitpid");
      exit(EXIT_FAILURE);
    } else {
      if (WIFSIGNALED(status)) { // if child terminated by signal
        signo = WTERMSIG(status);
        if (signo != SIGINT) { // if signal is not SIGINT
          perror("termsig");
          printf("child process killed by %s\n", strsignal(signo));
          exit(EXIT_FAILURE);
        } else { // child killed by SIGINT
          printf("Success\n");
        }
      } else { // child terminated by other method
        perror("ifsignaled");
        exit(EXIT_FAILURE);
      }
    }
  }
  return 0;
}