Linux Signal

mohadang·2023년 3월 11일
0

Linux System Programming

목록 보기
8/9
post-thumbnail
post-custom-banner

"Software interrupts that provide a mechanism for handling asynchronous events"

Interrupt는 예상하지 못한 비동기적인 이벤트이다.

Interrupt handling

  • 발생(raise : ex:keyboard) -> 보관(kernel queue) -> 처리(signal handling)

Signal Number

Unix/Linux에서는 signal 번호가 상수로 정의되어 있다.
Default action : 프로세스가 해당 signal을 받을때 기본 동작

Pending signal

아직 처리되지 않은 signal

Signal Handler

특정 signal을 처리하기 위해 지정된 함수
Default handler를 대체 할 수 있으나 SIGKILL, SIGSTOP에 대한 handler는 예외적으로 대체 불가능 하다.

  • Admin의 시스템 관리를 위해 필요

signal 등록

#include <signal.h>
sighandler_t signal signal(int signum, sighandler_t handler);

Handler

  • SIG_IGN : signal을 무시
  • SIG_DFL : system의 default handler로 처리

return

  • 기존 handler의 function pointer 반환 하거나 SIG_ERR반환

Signal 상속

Ignored : forks, execs 모두 상속 받음
Default : forks, execs 모두 상속 받음
Handled(시그널 처리 방식)

  • forks : 같은 프로그램이니 상속 받는다.
  • execs : 다른 프로그램이니 상속 받지 않는다.
    Pending signals(아직 처리 되지 않은 signal)
  • forks : 해당 signal은 부모에게 전달 된 것이기에 자식이 받을 필요 없다.
  • execs : 메모리는 새 프로세스로 교체되고 pid는 그대로 유지 된다. 커널은 pid를 보고 signal을 전달 함으로 새 프로세스에게 그대로 전달 한다.

kill

#include <syhs/types.h>
#include <signal.h>
int kill(pid_t pid, int signo);

kill은 signal을 보내는 system call이다
pid

  • 0 : 자신이 속한 process group 내 모든 process
  • -1 : 현재 process가 가진 권한으로 signal을 보낼 수 있는 모든 process
  • < -1 : GID == pid 인 process group

다른 프로세스에게 signal을 보내기 위해서는 적합한 권한을 가지고 있어야 한다.
필요 권한

  • Sender's (RUID or EUID) == receiver's (RUID or SavedUID, 내가 실행한 Process이다)
    • 내가 내 Process에게 signal 보내는 것은 상관 없다
  • Root는 모든 process에게 signal 전달 가능

권한 체크 방법

Null signal 활용 : 실제 signal을 전달하지 않으나 error checking은 수행

int ret = kill(pid, 0);
if(ret);//permission error
else;//ok

자신에게 시그널 보내기

#include <signal.h>
int raise(int sig);
void hand(int signo) {
  psignal(signo, "Received signal");
}
int main(void) {
  signal(SIGALRM, hand);
  alarm(2)//지정된 시간 후에 SIGALRM 발생
  printf("Wait...\n");
  sleep(3);
  return 0;
}

signal blocking

signal을 받지 않도록 blocking 할 수 있다

이렇게 막은 signal들은 pending signal이 된다
pending signal들은 blocking이 풀리면 전달 된다

siganl wait

특정 signal을 받을때 까지 대기할 수도 있다. 특정 signal을 받을때까지 대기 하는 동안 다른 signal은 무시

#include <signal.h>
int sigsuspend(const sigset_t* mask);

signal mask를 임시로 교체 후, block 되지 않은 signal이 도착할 때까지 대기
mask : 교체할 signal set의 주소

void handler(int signo) {
  psignal(signo, "Received signal : ");
}
int main(void) {
  sigset_t set;
  signal(SIGALRM, handler);// SIGALRM handler 설정
  sigfillset(&set);// 모든 signal bit 마스킹(1)
  sigdelset(&set, SIGALRM);// SIGALRM만 bit만 마스킹 제거(0)
  alarm(3);// 3초 후 SIGALRM
  printf("Wait..\n");
  sigsuspend(&set);// 임시로 signal mask 교체
}

SIGALRM이 올때까지 인터럽트 시그널이 발생 하여도 무시됨

profile
mohadang
post-custom-banner

0개의 댓글