signalfd(2) - wariua/manpages-ko GitHub Wiki
signalfd - μκ·Έλμ λ°κΈ° μν νμΌ λμ€ν¬λ¦½ν° λ§λ€κΈ°
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
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 νμΌ λμ€ν¬λ¦½ν°μμ 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 νμΌ λμ€ν¬λ¦½ν°μμ μ½κΈ°λ₯Ό νλ©΄ κ·Έ μ€λ λλ₯Ό ν₯ν μκ·Έλκ³Ό νλ‘μΈμ€(μ¦ μ€λ λ κ·Έλ£Ή μ 체)λ₯Ό ν₯ν μκ·Έλμ μ½κ² λλ€. (μ€λ λκ° νλ‘μΈμ€ λ΄ λ€λ₯Έ μ€λ λλ₯Ό ν₯ν μκ·Έλμ μ½μ μλ μλ€.)
μ±κ³΅ μ signalfd()
λ signalfd νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ°ννλ€. fd
κ° -1μ΄μμΌλ©΄ μ νμΌ λμ€ν¬λ¦½ν°μ΄κ³ , fd
κ° μ ν¨ν νμΌ λμ€ν¬λ¦½ν°μμΌλ©΄ fd
μ΄λ€. μ€λ₯ μ -1μ λ°ννλ©° μ€λ₯λ₯Ό λνλ΄λλ‘ errno
λ₯Ό μ€μ νλ€.
EBADF
-
fd
νμΌ λμ€ν¬λ¦½ν°κ° μ ν¨ν νμΌ λμ€ν¬λ¦½ν°κ° μλλ€. EINVAL
-
fd
κ° μ ν¨ν signalfd νμΌ λμ€ν¬λ¦½ν°κ° μλλ€. EINVAL
-
flags
κ° μ ν¨νμ§ μλ€. λλ 리λ μ€ 2.6.26 λλ μ΄μ μμflags
κ° 0μ΄ μλλ€. EMFILE
- μ΄λ¦° νμΌ λμ€ν¬λ¦½ν° κ°μμ λν νλ‘μΈμ€λ³ μ νμ λλ¬νλ€.
ENFILE
- μ΄λ¦° νμΌ μ΄κ°μμ λν μμ€ν μ μ μ νμ λλ¬νλ€.
ENODEV
- (λ΄λΆμ μΌλ‘ μ°λ) μ΅λͺ μμ΄λ Έλ μ₯μΉλ₯Ό λ§μ΄νΈ ν μ μμλ€.
ENOMEM
- μ signalfd νμΌ λμ€ν¬λ¦½ν°λ₯Ό μμ±νκΈ°μ λ©λͺ¨λ¦¬κ° μΆ©λΆνμ§ μμλ€.
리λ
μ€ μ»€λ 2.6.22λΆν° signalfd()
κ° μ¬μ© κ°λ₯νλ€. glibc λ²μ 2.8λΆν° μ λμνλ μ§μμ μ 곡νλ€. 리λ
μ€ μ»€λ 2.6.27λΆν° signalfd4()
μμ€ν
νΈμΆ(NOTES μ°Έκ³ )μ΄ μ¬μ© κ°λ₯νλ€.
signalfd()
μ signalfd4()
λ 리λ
μ€ μ μ©μ΄λ€.
νλ‘μΈμ€μμ 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)λ‘ κ°μνλ©΄ λλ€.
κΈ°λ° λ¦¬λ
μ€ μμ€ν
νΈμΆμμλ mask
μΈμμ ν¬κΈ°λ₯Ό μ§μ νλ size_t sizemask
μΈμλ₯Ό μΆκ°λ‘ μꡬνλ€. glibcμ signalfd()
λνΌ ν¨μμμ νμν κ°μ κΈ°λ° μμ€ν
νΈμΆμ μ 곡νκΈ° λλ¬Έμ λνΌ ν¨μμλ κ·Έ μΈμκ° μλ€.
κΈ°λ° μμ€ν
νΈμΆμ΄ λ κ°μ§ μλ€. signalfd()
μ λ μ΅μ μΈ signalfd4()
μ΄λ€. μμͺ½ μμ€ν
νΈμΆμ flags
μΈμλ₯Ό ꡬννμ§ μλλ€. λ€μͺ½ μμ€ν
νΈμΆμ μμ κΈ°μ ν flags
κ°λ€μ ꡬννλ€. glibc 2.9λΆν° signalfd()
λνΌ ν¨μμμ κ°λ₯ν κ²½μ° signalfd4()
λ₯Ό μ¬μ©νλ€.
2.6.25 μ μ 컀λμμλ sigqueue(3)λ‘ λ³΄λΈ μκ·Έλ λλ° λ°μ΄ν°κ° ssi_ptr
λ° ssi_int
νλμ μ±μμ§μ§ μλλ€.
μλ νλ‘κ·Έλ¨μ 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");
}
}
}
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