77
88#include "loop-utils.h"
99#include "safe-wrappers.h"
10- #include <signal.h>
1110
1211bool
1312init_loop_data (LoopData * ld ) {
@@ -29,16 +28,20 @@ init_loop_data(LoopData *ld) {
2928static int signal_write_fd = -1 ;
3029
3130static void
32- handle_signal (int sig_num , siginfo_t * si , void * ucontext UNUSED ) {
31+ handle_signal (int sig_num UNUSED , siginfo_t * si , void * ucontext UNUSED ) {
3332 int save_err = errno ;
34- char buf [8 ];
35- int32_t sigval = si -> si_value .sival_int , signum = sig_num ;
36- memcpy (buf , & signum , 4 );
37- memcpy (buf + 4 , & sigval , 4 );
38- while (signal_write_fd != -1 ) {
39- ssize_t ret = write (signal_write_fd , buf , 8 );
40- if (ret < 0 && errno == EINTR ) continue ;
41- break ;
33+ char * buf = (char * )si ;
34+ size_t sz = sizeof (siginfo_t );
35+ while (signal_write_fd != -1 && sz ) {
36+ // as long as sz is less than PIPE_BUF write will either write all or return -1 with EAGAIN
37+ // so we are guaranteed atomic writes
38+ ssize_t ret = write (signal_write_fd , buf , sz );
39+ if (ret <= 0 ) {
40+ if (errno == EINTR ) continue ;
41+ break ;
42+ }
43+ sz -= ret ;
44+ buf += ret ;
4245 }
4346 errno = save_err ;
4447}
@@ -109,8 +112,8 @@ install_signal_handlers(LoopData *ld) {
109112#else
110113 if (!self_pipe (ld -> signal_fds , true)) return false;
111114 signal_write_fd = ld -> signal_fds [1 ];
112- struct sigaction act = {.sa_sigaction = handle_signal , .sa_flags = SA_SIGINFO };
113- #define SA (which ) { if (sigaction(which, &act, NULL) != 0) return false; if (siginterrupt(which, false) != 0) return false; }
115+ struct sigaction act = {.sa_sigaction = handle_signal , .sa_flags = SA_SIGINFO | SA_RESTART };
116+ #define SA (which ) { if (sigaction(which, &act, NULL) != 0) return false; }
114117 SA (SIGINT ); SA (SIGTERM ); SA (SIGCHLD ); SA (SIGUSR1 ); SA (SIGUSR2 );
115118#undef SA
116119 ld -> signal_read_fd = ld -> signal_fds [0 ];
123126read_signals (int fd , handle_signal_func callback , void * data ) {
124127#ifdef HAS_SIGNAL_FD
125128 static struct signalfd_siginfo fdsi [32 ];
129+ siginfo_t si ;
126130 while (true) {
127131 ssize_t s = read (fd , & fdsi , sizeof (fdsi ));
128132 if (s < 0 ) {
@@ -137,10 +141,19 @@ read_signals(int fd, handle_signal_func callback, void *data) {
137141 log_error ("Incomplete signal read from signalfd" );
138142 break ;
139143 }
140- for (size_t i = 0 ; i < num_signals ; i ++ ) callback (fdsi [i ].ssi_signo , fdsi [i ].ssi_int , data );
144+ for (size_t i = 0 ; i < num_signals ; i ++ ) {
145+ si .si_signo = fdsi [i ].ssi_signo ;
146+ si .si_code = fdsi [i ].ssi_code ;
147+ si .si_pid = fdsi [i ].ssi_pid ;
148+ si .si_uid = fdsi [i ].ssi_uid ;
149+ si .si_addr = (void * )fdsi [i ].ssi_addr ;
150+ si .si_status = fdsi [i ].ssi_status ;
151+ si .si_value .sival_int = fdsi [i ].ssi_int ;
152+ callback (& si , data );
153+ }
141154 }
142155#else
143- static char buf [256 ];
156+ static char buf [sizeof ( siginfo_t ) * 8 ];
144157 static size_t buf_pos = 0 ;
145158 while (true) {
146159 ssize_t len = read (fd , buf + buf_pos , sizeof (buf ) - buf_pos );
@@ -150,11 +163,10 @@ read_signals(int fd, handle_signal_func callback, void *data) {
150163 break ;
151164 }
152165 buf_pos += len ;
153- while (buf_pos >= 8 ) {
154- int32_t * sdata = (int32_t * )buf ;
155- callback (sdata [0 ], sdata [1 ], data );
156- memmove (buf , buf + 8 , 8 );
157- buf_pos -= 8 ;
166+ while (buf_pos >= sizeof (siginfo_t )) {
167+ callback ((siginfo_t * )buf , data );
168+ memmove (buf , buf + sizeof (siginfo_t ), sizeof (siginfo_t ));
169+ buf_pos -= sizeof (siginfo_t );
158170 }
159171 if (len == 0 ) break ;
160172 }
0 commit comments