[Linux] kill(시스템 콜), 핸들러2
1. kill
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int pid, sig_num, result;
if (argc != 3)
{
exit(1);
}
pid = atoi(argv[1]);
sig_num = atoi(argv[2]);
result = kill(pid, sig_num);
printf("result = %d\n", result);
}
이 코드를 kill이라는 이름으로 컴파일했다면
./kill [pid] [signum]으로 기존의 kill처럼 사용이 가능하다.
즉, 시스템콜 kill(pid, signum)는 pid로 signum의 signal을 보내며, 명령어 kill 역시 시스템콜 kill을 통해 구현되었을 것이라고 유추해볼 수 있다.
이 때 result는 성공했을 때 0 실패했을 때 -1이 리턴되며, 접근권한이 없는 프로세스에 signal을 보내려 시도하면 -1이 리턴되는 것을 볼 수 있다.
2. 핸들러2
앞에서 배웠던 시그널 핸들러에 대해 더 자세하게 배워보자.
우선 signal(signum, SIG_IGN)이라고 작성할 수 있는데, 이렇게 작성하면 해당 signal은 무시되게 된다.
(예외사항, SIGKILL은 프로세스를 죽이는 signal로서 무시가 안된다.)
또한
signal(SIGINT, my_sig_handler)로 등록을 해놓고
void my_sig_handler (int signum)
{
signal(SIGINT, SID_DFL);
}
이렇게 하면 처음에 SIGINT를 받으면 my_signal_handler가 실행되었다가 한번 더 받으면 DEFAULT가 실행되어 프로그램이 죽게 된다.
signal handler는 조금 특별하다.
이런 식으로 어떤 함수가 수행되고 있다가 signal이 발생하면 SIG_IGN 가 아닌 이상 시그널 핸들러를 수행하고 다시 원래 수행되던 함수로 돌아온다.
이는 OS가 해주는 것이다.
그럼 signal handler가 수행되는 중 또 signal이 발생되면?
이 떄는 다른 signal handler가 호출되는 것이 아니라 기존 signal_handler를 수행하고 난 다음 signal_handler가 수행된다.
이 때 signal의 발생여부는 bit로 관리되므로 (True / False 여부) signal handler가 수행되는 중 똑같은 signal이 10번 발생되면 이 중 9번은 무시된다.
또한 sleep(5)는 원래 5초를 기다려야 하는데 그 사이에 signal이 들어오면 바로 꺠어나게 된다.