signalfd(2) - wariua/manpages-ko GitHub Wiki

NAME

signalfd - μ‹œκ·Έλ„μ„ λ°›κΈ° μœ„ν•œ 파일 λ””μŠ€ν¬λ¦½ν„° λ§Œλ“€κΈ°

SYNOPSIS

#include <sys/signalfd.h>

int signalfd(int fd, const sigset_t *mask, int flags);

DESCRIPTION

signalfd()λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μƒμ„±ν•˜λ©°, 이λ₯Ό μ΄μš©ν•΄ 호좜자λ₯Ό λŒ€μƒμœΌλ‘œ ν•˜λŠ” μ‹œκ·Έλ„μ„ 받을 수 μžˆλ‹€. μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ‚˜ sigwaitinfo(2) μ‚¬μš©μ˜ λŒ€μ•ˆμ΄ λ˜λŠ”λ°, select(2), poll(2), epoll(7)둜 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό κ°μ‹œν•  수 μžˆλ‹€λŠ” μž₯점이 μžˆλ‹€.

mask μΈμžλŠ” ν˜ΈμΆœμžκ°€ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 λ°›κ³  싢은 μ‹œκ·Έλ„λ“€μ˜ 집합을 λ‚˜νƒ€λ‚Έλ‹€. sigsetops(3)μ—μ„œ κΈ°μˆ ν•˜λŠ” λ§€ν¬λ‘œλ“€λ‘œ κ·Έ μ‹œκ·Έλ„ μ§‘ν•©μ˜ λ‚΄μš©μ„ μ΄ˆκΈ°ν™” ν•  수 μžˆλ‹€. 보톡은 κ·Έ μ‹œκ·Έλ„ 집합을 sigprocmask(2)둜 차단해야 ν•˜λŠ”λ°, 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 μˆ˜μ‹ ν•  μ‹œκ·Έλ„λ“€μ΄ κΈ°λ³Έ 처리 방식에 따라 μ²˜λ¦¬λ˜λŠ” 것을 막기 μœ„ν•΄μ„œμ΄λ‹€. signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 SIGKILLμ΄λ‚˜ SIGSTOP μ‹œκ·Έλ„μ„ λ°›λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€. mask에 κ·Έ μ‹œκ·Έλ„λ“€μ„ μ§€μ •ν•˜λ©΄ 쑰용히 λ¬΄μ‹œλœλ‹€.

fd μΈμžκ°€ -1이면 ν˜ΈμΆœμ—μ„œ μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μƒμ„±ν•˜κ³  mask에 μ§€μ •ν•œ μ‹œκ·Έλ„ 집합을 κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°μ— μ—°κ³„ν•œλ‹€. fdκ°€ -1이 μ•„λ‹ˆλ©΄ μœ νš¨ν•œ κΈ°μ‘΄ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μ§€μ •ν•΄μ•Ό ν•˜λ©°, κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°μ— μ—°κ³„λœ μ‹œκ·Έλ„ 집합이 mask둜 κ΅μ²΄λœλ‹€.

λ¦¬λˆ…μŠ€ 2.6.27λΆ€ν„° flags에 λ‹€μŒ 값듀을 λΉ„νŠΈ OR ν•΄μ„œ signalfd()의 λ™μž‘ 방식을 λ°”κΏ€ 수 μžˆλ‹€.

SFD_NONBLOCK
μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ κ°€λ¦¬ν‚€λŠ” μ—΄λ¦° 파일 기술 ν•­λͺ©(open(2) μ°Έκ³ )에 O_NONBLOCK 파일 μƒνƒœ ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œλ‹€. 이 ν”Œλž˜κ·Έλ₯Ό μ‚¬μš©ν•˜λ©΄ 같은 κ²°κ³Όλ₯Ό μ–»κΈ° μœ„ν•΄ fcntl(2)을 μΆ”κ°€λ‘œ ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.
SFD_CLOEXEC
μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°μ— 'execμ—μ„œ λ‹«κΈ°'(FD_CLOEXEC) ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œλ‹€. 이게 μœ μš©ν•  수 μžˆλŠ” μ΄μœ μ— λŒ€ν•΄μ„  open(2)의 O_CLOEXEC ν”Œλž˜κ·Έ μ„€λͺ…을 보라.

λ¦¬λˆ…μŠ€ 버전 2.6.26κΉŒμ§€λŠ” flags 인자λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©° 0으둜 μ§€μ •ν•΄μ•Ό ν•œλ‹€.

signalfd()κ°€ λ°˜ν™˜ν•˜λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” λ‹€μŒ μž‘μ—…μ„ μ§€μ›ν•œλ‹€.

read(2)

mask에 μ§€μ •ν•œ μ‹œκ·Έλ„λ“€μ΄ ν•˜λ‚˜ 이상 ν”„λ‘œμ„ΈμŠ€μ— 미처리 μƒνƒœμ΄λ©΄ read(2)에 μ€€ 버퍼λ₯Ό μ΄μš©ν•΄ μ‹œκ·Έλ„μ„ κΈ°μˆ ν•˜λŠ” signalfd_siginfo ꡬ쑰체(μ•„λž˜ μ°Έκ³ )λ₯Ό ν•˜λ‚˜ 이상 λ°˜ν™˜ν•œλ‹€. 미처리 μ‹œκ·Έλ„μ— λŒ€ν•œ 정보λ₯Ό 버퍼에 가급적 많이 μ±„μ›Œμ„œ read(2)κ°€ λ°˜ν™˜ν•œλ‹€. 버퍼가 μ΅œμ†Œ sizeof(struct signalfd_siginfo) λ°”μ΄νŠΈμ—¬μ•Ό ν•œλ‹€. read(2)의 λ°˜ν™˜ 값은 읽은 λ°”μ΄νŠΈ μ΄μˆ˜μ΄λ‹€.

read(2)의 결과둜 μ‹œκ·Έλ„μ΄ μ†ŒλΉ„λ˜λ©°, κ·Έλž˜μ„œ 더 이상 κ·Έ ν”„λ‘œμ„ΈμŠ€μ— 미처리인 μ‹œκ·Έλ„μ΄ μ•„λ‹ˆκ²Œ λœλ‹€. (즉, μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ— μž‘νžˆμ§€ μ•ŠμœΌλ©° sigwaitinfo(2)둜 받을 수 μ—†λ‹€.)

mask λ‚΄μ˜ μ‹œκ·Έλ„ μ–΄λŠ 것도 ν”„λ‘œμ„ΈμŠ€μ— 미처리 μƒνƒœκ°€ μ•„λ‹ˆλ©΄ mask λ‚΄μ˜ μ‹œκ·Έλ„λ“€ 쀑 ν•˜λ‚˜κ°€ ν”„λ‘œμ„ΈμŠ€μ—κ²Œ 생성될 λ•ŒκΉŒμ§€ read(2)κ°€ 블둝 ν•œλ‹€. 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ…ΌλΈ”λ‘μœΌλ‘œ λ§Œλ“€μ—ˆμœΌλ©΄ EAGAIN 였λ₯˜λ‘œ μ‹€νŒ¨ν•œλ‹€.

poll(2), select(2) (기타 μœ μ‚¬ ν•¨μˆ˜)

mask λ‚΄μ˜ μ‹œκ·Έλ„μ΄ ν•˜λ‚˜ 이상 ν”„λ‘œμ„ΈμŠ€μ— 미처리 μƒνƒœμΈ κ²½μš°μ— 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ 읽기 κ°€λŠ₯ν•˜λ‹€. (select(2) readfds 인자, poll(2) POLLIN ν”Œλž˜κ·Έ.)

signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” pselect(2), ppoll(2), epoll(7) 같은 λ‹€λ₯Έ 파일 λ””μŠ€ν¬λ¦½ν„° 닀쀑화 API도 μ§€μ›ν•œλ‹€.

close(2)
파일 λ””μŠ€ν¬λ¦½ν„°κ°€ 더 이상 ν•„μš”ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹«μ•„μ•Ό ν•œλ‹€. 동일 signalfd 객체에 μ—°κ³„λœ λͺ¨λ“  파일 λ””μŠ€ν¬λ¦½ν„°κ°€ λ‹«ν˜”μ„ λ•Œ 컀널이 κ·Έ 객체의 μžμ›μ„ ν•΄μ œν•œλ‹€.

signalfd_siginfo ꡬ쑰체

signalfd 파일 λ””μŠ€ν¬λ¦½ν„°μ—μ„œ read(2)κ°€ λ°˜ν™˜ν•˜λŠ” signalfd_siginfo ꡬ쑰체의 ν˜•μ‹μ€ λ‹€μŒκ³Ό κ°™λ‹€.

struct signalfd_siginfo {
    uint32_t ssi_signo;    /* μ‹œκ·Έλ„ 번호 */
    int32_t  ssi_errno;    /* 였λ₯˜ 번호 (μ‚¬μš© μ•ˆ 함) */
    int32_t  ssi_code;     /* μ‹œκ·Έλ„ μ½”λ“œ */
    uint32_t ssi_pid;      /* μ†‘μ‹ μžμ˜ PID */
    uint32_t ssi_uid;      /* μ†‘μ‹ μžμ˜ μ‹€μ œ UID */
    int32_t  ssi_fd;       /* 파일 λ””μŠ€ν¬λ¦½ν„° (SIGIO) */
    uint32_t ssi_tid;      /* 컀널 타이머 ID (POSIX 타이머) */
    uint32_t ssi_band;     /* λ°΄λ“œ 이벀트 (SIGIO) */
    uint32_t ssi_overrun;  /* POSIX 타이머 초과 횟수 */
    uint32_t ssi_trapno;   /* μ‹œκ·Έλ„μ„ μœ λ°œν•œ 트랩 번호 */
    int32_t  ssi_status;   /* μ’…λ£Œ μƒνƒœ λ˜λŠ” μ‹œκ·Έλ„ (SIGCHLD) */
    int32_t  ssi_int;      /* sigqueue(3)둜 보낸 μ •μˆ˜ */
    uint64_t ssi_ptr;      /* sigqueue(3)둜 보낸 포인터 */
    uint64_t ssi_utime;    /* μ‚¬μš©μž CPU μ†Œλͺ¨ μ‹œκ°„ (SIGCHLD) */
    uint64_t ssi_stime;    /* μ‹œμŠ€ν…œ CPU μ†Œλͺ¨ μ‹œκ°„ (SIGCHLD) */
    uint64_t ssi_addr;     /* μ‹œκ·Έλ„μ„ μƒμ„±ν•œ μ£Όμ†Œ
                              (ν•˜λ“œμ›¨μ–΄ 생성 μ‹œκ·Έλ„μ—μ„œ) */
    uint16_t ssi_addr_lsb; /* μ£Όμ†Œμ˜ μ΅œν•˜μœ„ λΉ„νŠΈ
                              (SIGBUS, λ¦¬λˆ…μŠ€ 2.6.37λΆ€ν„°) */
    uint8_t  pad[X];       /* 128λ°”μ΄νŠΈλ‘œ μ±„μš°λŠ” νŒ¨λ“œ
                              (ν–₯ν›„ ν•„λ“œ μΆ”κ°€ κ°€λŠ₯) */
};

이 ꡬ쑰체의 각 ν•„λ“œλŠ” siginfo_t ꡬ쑰체의 λΉ„μŠ·ν•œ μ΄λ¦„μ˜ ν•„λ“œμ™€ μœ μ‚¬ν•˜λ‹€. siginfo_t κ΅¬μ‘°μ²΄λŠ” sigaction(2)μ—μ„œ μ„€λͺ…ν•œλ‹€. νŠΉμ • μ‹œκ·Έλ„μ— λŒ€ν•΄ λ°˜ν™˜λœ signalfd_siginfo ꡬ쑰체의 λͺ¨λ“  ν•„λ“œκ°€ μœ νš¨ν•œ 것은 μ•„λ‹ˆλ‹€. ssi_code ν•„λ“œμ— λ°˜ν™˜λœ κ°’μœΌλ‘œλΆ€ν„° μœ νš¨ν•œ ν•„λ“œλ“€μ˜ 집합을 μ•Œμ•„λ‚Ό 수 μžˆλ‹€. κ·Έ ν•„λ“œλŠ” siginfo_t의 si_code ν•„λ“œμ— λŒ€μ‘ν•œλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ sigaction(2) μ°Έκ³ .

fork(2) λ™μž‘ 방식

fork(2) 후에 μžμ‹μ΄ signalfd 파일 λ””μŠ€ν¬λ¦½ν„° 사본을 λ¬Όλ €λ°›λŠ”λ‹€. μžμ‹μ—μ„œ κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°μ— read(2) ν•˜λ©΄ μžμ‹μ˜ 큐에 μžˆλŠ” μ‹œκ·Έλ„μ— λŒ€ν•œ 정보λ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

파일 λ””μŠ€ν¬λ¦½ν„° 전달 λ™μž‘ 방식

λ‹€λ₯Έ 파일 λ””μŠ€ν¬λ¦½ν„°λ“€κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ μœ λ‹‰μŠ€ 도메인 μ†ŒμΌ“μ„ 톡해 signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€λ‘œ 전달할 수 μžˆλ‹€. (unix(7) μ°Έκ³ .) μˆ˜μ‹  μͺ½ ν”„λ‘œμ„ΈμŠ€μ—μ„œ μˆ˜μ‹ ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°μ— read(2) ν•˜λ©΄ κ·Έ ν”„λ‘œμ„ΈμŠ€μ˜ 큐에 μžˆλŠ” μ‹œκ·Έλ„μ— λŒ€ν•œ 정보λ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

execve(2) λ™μž‘ 방식

λ‹€λ₯Έ 파일 λ””μŠ€ν¬λ¦½ν„°λ“€κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 'execμ—μ„œ λ‹«κΈ°' ν”Œλž˜κ·Έ(fcntl(2) μ°Έκ³ ) ν‘œμ‹œλ₯Ό ν•˜μ§€ μ•Šμ•˜μœΌλ©΄ execve(2)λ₯Ό κ±°μΉ˜λ©΄μ„œ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ—΄λ¦° μ±„λ‘œ μœ μ§€λœλ‹€. execve(2) 전에 읽기가 κ°€λŠ₯ν–ˆλ˜ μ‹œκ·Έλ„μ΄ 있으면 μƒˆλ‘œ 적재된 ν”„λ‘œκ·Έλž¨μ—κ²Œ 읽기 κ°€λŠ₯ν•˜κ²Œ μœ μ§€λœλ‹€. (미처리인 차단 μ‹œκ·Έλ„μ΄ execve(2)λ₯Ό κ±°μΉ˜λ©΄μ„œ 미처리둜 μœ μ§€λ˜λŠ” 전톡적 μ‹œκ·Έλ„ λ™μž‘ 방식과 μœ μ‚¬ν•˜λ‹€.)

μŠ€λ ˆλ“œ λ™μž‘ 방식

닀쀑 μŠ€λ ˆλ“œ ν”„λ‘œκ·Έλž¨μ—μ„œ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°μ˜ λ™μž‘ 방식은 μ‹œκ·Έλ„μ˜ ν‘œμ€€ λ™μž‘ 방식을 λ°˜μ˜ν•œλ‹€. λ‹€μ‹œ 말해 μŠ€λ ˆλ“œκ°€ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°μ—μ„œ 읽기λ₯Ό ν•˜λ©΄ κ·Έ μŠ€λ ˆλ“œλ₯Ό ν–₯ν•œ μ‹œκ·Έλ„κ³Ό ν”„λ‘œμ„ΈμŠ€(즉 μŠ€λ ˆλ“œ κ·Έλ£Ή 전체)λ₯Ό ν–₯ν•œ μ‹œκ·Έλ„μ„ 읽게 λœλ‹€. (μŠ€λ ˆλ“œκ°€ ν”„λ‘œμ„ΈμŠ€ λ‚΄ λ‹€λ₯Έ μŠ€λ ˆλ“œλ₯Ό ν–₯ν•œ μ‹œκ·Έλ„μ„ 읽을 μˆ˜λŠ” μ—†λ‹€.)

RETURN VALUE

성곡 μ‹œ signalfd()λŠ” signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€. fdκ°€ -1μ΄μ—ˆμœΌλ©΄ μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°μ΄κ³ , fdκ°€ μœ νš¨ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°μ˜€μœΌλ©΄ fd이닀. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ„λ‘ errnoλ₯Ό μ„€μ •ν•œλ‹€.

ERRORS

EBADF
fd 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μœ νš¨ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ•„λ‹ˆλ‹€.
EINVAL
fdκ°€ μœ νš¨ν•œ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ•„λ‹ˆλ‹€.
EINVAL
flagsκ°€ μœ νš¨ν•˜μ§€ μ•Šλ‹€. λ˜λŠ” λ¦¬λˆ…μŠ€ 2.6.26 λ˜λŠ” μ΄μ „μ—μ„œ flagsκ°€ 0이 μ•„λ‹ˆλ‹€.
EMFILE
μ—΄λ¦° 파일 λ””μŠ€ν¬λ¦½ν„° κ°œμˆ˜μ— λŒ€ν•œ ν”„λ‘œμ„ΈμŠ€λ³„ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENFILE
μ—΄λ¦° 파일 μ΄κ°œμˆ˜μ— λŒ€ν•œ μ‹œμŠ€ν…œ μ „μ—­ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENODEV
(λ‚΄λΆ€μ μœΌλ‘œ μ“°λŠ”) 읡λͺ… μ•„μ΄λ…Έλ“œ μž₯치λ₯Ό 마운트 ν•  수 μ—†μ—ˆλ‹€.
ENOMEM
μƒˆ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μƒμ„±ν•˜κΈ°μ— λ©”λͺ¨λ¦¬κ°€ μΆ©λΆ„ν•˜μ§€ μ•Šμ•˜λ‹€.

VERSIONS

λ¦¬λˆ…μŠ€ 컀널 2.6.22λΆ€ν„° signalfd()κ°€ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. glibc 버전 2.8λΆ€ν„° 잘 λ™μž‘ν•˜λŠ” 지원을 μ œκ³΅ν•œλ‹€. λ¦¬λˆ…μŠ€ 컀널 2.6.27λΆ€ν„° signalfd4() μ‹œμŠ€ν…œ 호좜(NOTES μ°Έκ³ )이 μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.

CONFORMING TO

signalfd()와 signalfd4()λŠ” λ¦¬λˆ…μŠ€ μ „μš©μ΄λ‹€.

NOTES

ν”„λ‘œμ„ΈμŠ€μ—μ„œ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό μ—¬λŸ¬ 개 λ§Œλ“€ 수 μžˆλ‹€. κ·Έλž˜μ„œ 각 파일 λ””μŠ€ν¬λ¦½ν„°λ‘œ λ‹€λ₯Έ μ‹œκ·Έλ„μ„ λ°›λŠ” 게 κ°€λŠ₯ν•˜λ‹€. (select(2), poll(2), epoll(7)둜 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό κ°μ‹œν•˜λŠ” κ²½μš°μ— μœ μš©ν•  수 μžˆλ‹€. λ„μ°©ν•˜λŠ” μ‹œκ·Έλ„μ— 따라 λ‹€λ₯Έ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ€€λΉ„ μƒνƒœκ°€ λœλ‹€.) ν•œ μ‹œκ·Έλ„μ΄ μ—¬λŸ¬ 파일 λ””μŠ€ν¬λ¦½ν„°μ˜ mask에 λ“±μž₯ν•˜λŠ” κ²½μš°μ—λŠ” κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°λ“€ 쀑 μ–΄λŠ κ²ƒμ—μ„œλ„ κ·Έ μ‹œκ·Έλ„μ˜ λ°œμƒμ„ (ν•œ 번) 읽을 수 μžˆλ‹€.

mask에 SIGKILLμ΄λ‚˜ SIGSTOP을 ν¬ν•¨μ‹œν‚€λ €λŠ” μ‹œλ„λŠ” 쑰용히 λ¬΄μ‹œλœλ‹€.

ν”„λ‘œμ„ΈμŠ€μ˜ /proc/[pid]/fdinfo 디렉터리 λ‚΄μ˜ λŒ€μ‘ν•˜λŠ” 파일 λ””μŠ€ν¬λ¦½ν„° ν•­λͺ©μ„ 톡해 signalfd 파일 λ””μŠ€ν¬λ¦½ν„°μ—μ„œ μ“°λŠ” μ‹œκ·Έλ„ 마슀크λ₯Ό λ³Ό 수 μžˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ proc(5) μ°Έκ³ .

ν•œκ³„

λΉ„μœ νš¨ λ©”λͺ¨λ¦¬ μ£Όμ†Œ μ ‘κ·ΌμœΌλ‘œ μΈν•œ SIGSEGVλ‚˜ μ‚°μˆ  였λ₯˜λ‘œ μΈν•œ SIGFPE처럼 λ™κΈ°μ μœΌλ‘œ μƒμ„±λ˜λŠ” μ‹œκ·Έλ„μ„ λ°›λŠ” 데 signalfd λ©”μ»€λ‹ˆμ¦˜μ„ μ΄μš©ν•  수 μ—†λ‹€. 그런 μ‹œκ·Έλ„μ€ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό ν†΅ν•΄μ„œλ§Œ μž‘μ„ 수 μžˆλ‹€.

μ•žμ„œ κΈ°μˆ ν•œ κ²ƒμ²˜λŸΌ 일반적인 μ‚¬μš© λ°©μ‹μ—μ„œλŠ” signalfd()λ₯Ό 톡해 받을 μ‹œκ·Έλ„λ“€μ„ 막아 λ‘”λ‹€. μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§Œλ“€μ–΄μ„œ (signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό ν•„μš”λ‘œ ν•˜μ§€ μ•ŠλŠ”) μ–΄λ–€ 헬퍼 ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ €λŠ” 경우라면 보톡은 fork(2)λ₯Ό ν˜ΈμΆœν•œ λ‹€μŒ execve(2) 호좜 전에 κ·Έ μ‹œκ·Έλ„λ“€μ„ ν’€μ–΄μ„œ 헬퍼 ν”„λ‘œκ·Έλž¨μ΄ κΈ°λŒ€ν•˜λŠ” μ‹œκ·Έλ„μ„ λ³Ό 수 μžˆλ„λ‘ ν•˜κ³  싢을 것이닀. ν•˜μ§€λ§Œ ν”„λ‘œκ·Έλž¨μ—μ„œ ν˜ΈμΆœν•˜λŠ” μ–΄λ–€ 라이브러리 ν•¨μˆ˜μ— μ˜ν•΄ λ¬΄λŒ€ λ’€μ—μ„œ 헬퍼 ν”„λ‘œκ·Έλž¨μ΄ μƒμ„±λ˜λŠ” κ²½μš°μ—λŠ” 그게 λΆˆκ°€λŠ₯ν•  것이닀. 그런 κ²½μš°μ—λŠ” 전톡적인 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ‘œ 후퇴해야 ν•œλ‹€. ν•Έλ“€λŸ¬μ—μ„œ μ–΄λ–€ 파일 λ””μŠ€ν¬λ¦½ν„°μ— μ“°κΈ°λ₯Ό ν•˜κ³  κ·Έκ±Έ select(2), poll(2), epoll(7)둜 κ°μ‹œν•˜λ©΄ λœλ‹€.

C 라이브러리/컀널 차이

기반 λ¦¬λˆ…μŠ€ μ‹œμŠ€ν…œ ν˜ΈμΆœμ—μ„œλŠ” mask 인자의 크기λ₯Ό μ§€μ •ν•˜λŠ” size_t sizemask 인자λ₯Ό μΆ”κ°€λ‘œ μš”κ΅¬ν•œλ‹€. glibc의 signalfd() 래퍼 ν•¨μˆ˜μ—μ„œ ν•„μš”ν•œ 값을 기반 μ‹œμŠ€ν…œ ν˜ΈμΆœμ— μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ— 래퍼 ν•¨μˆ˜μ—λŠ” κ·Έ μΈμžκ°€ μ—†λ‹€.

기반 μ‹œμŠ€ν…œ 호좜이 두 κ°€μ§€ μžˆλ‹€. signalfd()와 더 μ΅œμ‹ μΈ signalfd4()이닀. μ•žμͺ½ μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ flags 인자λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ”λ‹€. λ’€μͺ½ μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ μœ„μ— κΈ°μˆ ν•œ flags 값듀을 κ΅¬ν˜„ν•œλ‹€. glibc 2.9λΆ€ν„° signalfd() 래퍼 ν•¨μˆ˜μ—μ„œ κ°€λŠ₯ν•œ 경우 signalfd4()λ₯Ό μ‚¬μš©ν•œλ‹€.

BUGS

2.6.25 μ „μ˜ μ»€λ„μ—μ„œλŠ” sigqueue(3)둜 보낸 μ‹œκ·Έλ„ λ™λ°˜ 데이터가 ssi_ptr 및 ssi_int ν•„λ“œμ— μ±„μ›Œμ§€μ§€ μ•ŠλŠ”λ‹€.

EXAMPLE

μ•„λž˜ ν”„λ‘œκ·Έλž¨μ€ signalfd 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 μ‹œκ·Έλ„ SIGINT와 SIGQUIT을 λ°›λŠ”λ‹€. SIGQUIT μ‹œκ·Έλ„μ„ 받은 후에 ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œν•œλ‹€. λ‹€μŒ μ…Έ μ„Έμ…˜μ΄ ν”„λ‘œκ·Έλž¨ μ‚¬μš© 방식을 보여 μ€€λ‹€.

$ ./signalfd_demo
^C                   # Control-C둜 SIGINT 생성
Got SIGINT
^C
Got SIGINT
^\                   # Control-\둜 SIGQUIT 생성
Got SIGQUIT
$

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€

#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
    sigset_t mask;
    int sfd;
    struct signalfd_siginfo fdsi;
    ssize_t s;

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);

    /* μ‹œκ·Έλ„μ„ λ§‰μ•„μ„œ κΈ°λ³Έ 처리 방식에 따라
       μ²˜λ¦¬λ˜μ§€ μ•Šλ„λ‘ 함 */

    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
        handle_error("sigprocmask");

    sfd = signalfd(-1, &mask, 0);
    if (sfd == -1)
        handle_error("signalfd");

    for (;;) {
        s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
        if (s != sizeof(struct signalfd_siginfo))
            handle_error("read");

        if (fdsi.ssi_signo == SIGINT) {
            printf("Got SIGINT\n");
        } else if (fdsi.ssi_signo == SIGQUIT) {
            printf("Got SIGQUIT\n");
            exit(EXIT_SUCCESS);
        } else {
            printf("Read unexpected signal\n");
        }
    }
}

SEE ALSO

eventfd(2), poll(2), read(2), select(2), sigaction(2), sigprocmask(2), sigwaitinfo(2), timerfd_create(2), sigsetops(3), sigwait(3), epoll(7), signal(7)


2019-03-06

⚠️ **GitHub.com Fallback** ⚠️