본문 바로가기
42seoul/circle-2

[ minitalk ] 시그널 함수 <signal.h>

by saniii 2022. 2. 23.

 

 

# signal

시그널 처리하는 방법을 설정하는 함수

void (*signal(int signum, void (*handler)(int)))(int);

이전에 설정된 시그널 핸들러를 반환한다. : void *()(int)

- int signum : 시그널 넘버

- void (*handler)(int) : 시그널을 처리할 핸들러

 

+ 시그널의 종류       

1) SIGHUP 2) SIGINT  3) SIGQUIT 4) SIGILL  5) SIGTRAP 6) SIGABRT 7) SIGBUS  8) SIGFPE 
9) SIGKILL  10) SIGUSR1  11) SIGSEGV 12) SIGUSR2  13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
  18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22)SIGTTOU 23) SIGURG  24)SIGXCPU
25)
SIGXFSZ
26)
SIGVTALRM
27) SIGPROF 28)
SIGWINCH
29) SIGIO  30) SIGPWR  31) SIGSYS 32)
SIGRTMIN

 

** 일반적으로 유닉스에서의 signal은 한번 시그널을 받은 후에, 그 수명을 다하기 때문에  다시 시그널을 받으려면  재정의 해줘야 한다

 

 

# sigemptyset

시그널 집합 변수의 내용을 모두 제거한다.

int sigemptyset(sigset_t *set);

시그널 집합 변수를 성공적으로 삭제하면 0을 반환, 실패하면 -1을 반환

 

 

 

# sigaddset

시그널 집합 변수에 시그널을 추가하는 함수

(삭제하는 건 sigdelset())

#include <signal.h>

int sigaddset(sigset_t *set, int signum);

집합 변수를 추가하는데 성공하면 0을 반환, 실패하면 -1을 반환

- sigset_t *set: 시그널 집합 변수

- int signum : 시그널 넘버

(*set에 시그널 signum을 추가한다.)

 

 

 

# sigaction

특정 신호를 수신할 때 프로세스가 수행하는 action을 설정, 변경한다. 

signal()과 달리 시그널을 객체로 다룰 수 있다.

#include <signal.h>

int sigaction(int signum, const struct sigaction *restrict act, struct sigaction *restrict oldact);

성공하면 0을 반환하고 오류가 발생하면 -1이 반환된다. (errno에 오류의 종류를 저장)

- int signum : 시그널 넘버 (SIGKILL, SIGSTOP을 제외한 모든 시그널이 들어올 수 있다.)

- struct sigaction *act : 새롭게 지정할 프로세스

- struct sigaction *oldact : 새롭게 지정하기 전에 이미 지정되어 있던 프로세스를 이곳에 저장

(**  *restrict : 각 포인터가 서로 다른 메모리 공간을 가리키고 있고, 다른 곳에서 접근하지 않으니 컴파일러가 최적화를 하라는 뜻)

 

sigaction 함수는 sigaction 구조체를 선언하여 구조체 내부에 핸들러 함수를 등록하여 시그널을 다룬다.

+ sigaction 구조

struct sigaction {
	void     (*sa_handler)(int);
	void     (*sa_sigaction)(int, siginfo_t *, void *);
	sigset_t   sa_mask;
	int        sa_flags;
	void     (*sa_restorer)(void);
};

- void     (*sa_handler)(int);  : 시그널(signum)을 수신하면 실행할 함수(핸들러)
- void     (*sa_sigaction)(int, siginfo_t *, void *); : sa_flags가 SA_SIGINFO일 때 sa_handler 대신 동작하는 핸들러

  • sa_handler보다 인자가 더 많다. 

- sigset_t   sa_mask; : 시그널을 처리하는 동안 블록할 시그널의 마스크를 제공한다.
- int        sa_flags; : 각 의미가 다른 여러 종류의 플래그를 사용할 수 있으며 OR 연산자로 여러개를 동시에 지정하여 사용할 수 있다.

  • SA_SIGINFO : 시그널 처리기가 하나가 아니라 3개의 인자를 취할 경우 sa_handler대신 sigaction의 siginfo_t를 사용할 수 있다.  

- void     (*sa_restorer)(void); : 사용하면 안된다. 

 

 

*  sigaction은 안정된 신호체제를 제공한다. 

+ siginfo_t 구조

siginfo_t {
    int      si_signo;  /* 시그널 넘버 */
    int      si_errno;  /* errno 값 */
    int      si_code;   /* 시그널 코드 */
    pid_t    si_pid;    /* 전송하는 프로세스 ID  */
    uid_t    si_uid;    /* 프로세스를 전송하는 실제 사용자 ID */
    int      si_status; /* Exit 값 또는 시그널 */
    clock_t  si_utime;  /* 소모된 사용자 시간 */
    clock_t  si_stime;  /* 소모된 시스템 시간 */
    sigval_t si_value;  /* 시그널 값 */
    int      si_int;    /* POSIX.1b 시그널 */
    void *   si_ptr;    /* POSIX.1b 시그널 */
    void *   si_addr;   /* 실패를 초래한 메모리 위치 */
    int      si_band;   /* 밴드 이벤트 */
    int      si_fd;     /* 파일 기술자 */
}

 

[ 참고 : https://www.joinc.co.kr/w/man/2/sigaction ]

[ 참고 : https://tdoodle.tistory.com/entry/%EC%8B%9C%EA%B7%B8%EB%84%90%EC%9D%98-%EB%AA%A8%EB%93%A0%EA%B2%83-All-about-Linux-signals ]

 

 

 

 

# kill

프로세스에 시그널을 전송. 시스템 호출을 사용하여 프로세스 그룹이나 프로세스에 모든 신호를 보낼 수 있다. 

(** shell 명령어 kill은 프로세스를 죽인다.)

#include <signal.h>

int kill(pid_t pid, int signum);

성공하면 0을 반환하고, 실패하면 -1을 반환

- pid_t pid : KILL 대상 프로세스 ID

- int signum : 시그널 넘버

 

pid > 0 : 지정한 프로세스 ID에만 시그널을 전송
pid == 0 : 시그널은 함수를 호출한 프로세스가 속한 그룹의 모든 프로세스에  시그널을 전송
pid == -1 : 프로세스1(init)을 제외하고 함수를 호출한 프로세스가 신호를 보낼 수 있는 권한을 가진  모든 프로세스로 시그널을 전송
pid < 0 && pid != -1 : 

(프로세스가 신호를 보낼 수 있는 권한을 가지려면 권한이 있거나(리눅스에서는 대상 프로세스의 사용자 네임스페이스에 CAP_KILL 기능이 있음) 전송 프로세스의 실제 사용자 ID 또는 저장된 사용자 ID와 동일해야 합니다. SIGCONT의 경우 송수신 프로세스가 동일한 세션에 속할 때 충분합니다.) 

 

 

 

 

'42seoul > circle-2' 카테고리의 다른 글

[minitalk] 발전방향  (0) 2022.02.26
[ minitalk ] 구현과정  (0) 2022.02.25
[ minitalk ] getpid() | pause() | sleep() | usleep() | exit()  (0) 2022.02.24
[minitalk] 1. UNIX signal  (0) 2022.02.22
[ minitalk ] 0. 과제이해하기  (0) 2022.02.16

댓글