2323#include <sys/types.h>
2424#include <sys/stat.h>
2525#include <sys/socket.h>
26+ #include <sys/signalfd.h>
2627
2728#include <stdbool.h>
2829#include <unistd.h>
@@ -106,6 +107,9 @@ tlshd_accept_nl_policy[HANDSHAKE_A_ACCEPT_MAX + 1] = {
106107
107108static struct nl_sock * tlshd_notification_nls ;
108109
110+ static sigset_t tlshd_sig_poll_mask ;
111+ static int tlshd_sig_poll_fd ;
112+
109113static int tlshd_genl_event_handler (struct nl_msg * msg ,
110114 __attribute__ ((unused )) void * arg )
111115{
@@ -127,6 +131,9 @@ static int tlshd_genl_event_handler(struct nl_msg *msg,
127131
128132 if (!fork ()) {
129133 /* child */
134+ close (tlshd_sig_poll_fd );
135+ sigprocmask (SIG_UNBLOCK , & tlshd_sig_poll_mask , NULL );
136+
130137 nlmsg_free (msg );
131138 tlshd_genl_sock_close (tlshd_notification_nls );
132139
@@ -146,8 +153,13 @@ static int tlshd_genl_event_handler(struct nl_msg *msg,
146153 */
147154void tlshd_genl_dispatch (void )
148155{
156+ struct pollfd poll_fds [2 ];
149157 int err , mcgrp ;
150158
159+ /* Initialise signal poll mask */
160+ sigemptyset (& tlshd_sig_poll_mask );
161+ sigaddset (& tlshd_sig_poll_mask , SIGINT );
162+
151163 err = tlshd_genl_sock_open (& tlshd_notification_nls );
152164 if (err )
153165 return ;
@@ -174,14 +186,46 @@ void tlshd_genl_dispatch(void)
174186 }
175187
176188 nl_socket_disable_seq_check (tlshd_notification_nls );
177- while (true) {
178- err = nl_recvmsgs_default (tlshd_notification_nls );
179- if (err < 0 ) {
180- tlshd_log_nl_error ("nl_recvmsgs" , err );
189+
190+ err = nl_socket_set_nonblocking (tlshd_notification_nls );
191+ if (err != NLE_SUCCESS ) {
192+ tlshd_log_nl_error ("nl_socket_set_nonblocking" , err );
193+ goto out_close ;
194+ }
195+
196+ if (sigprocmask (SIG_BLOCK , & tlshd_sig_poll_mask , NULL )) {
197+ tlshd_log_perror ("sigprocmask" );
198+ goto out_close ;
199+ }
200+
201+ tlshd_sig_poll_fd = signalfd (-1 , & tlshd_sig_poll_mask ,
202+ SFD_NONBLOCK | SFD_CLOEXEC );
203+ if (tlshd_sig_poll_fd < 0 ) {
204+ tlshd_log_perror ("signalfd" );
205+ goto out_close ;
206+ }
207+
208+ poll_fds [0 ].fd = nl_socket_get_fd (tlshd_notification_nls );
209+ poll_fds [0 ].events = POLLIN ;
210+ poll_fds [1 ].fd = tlshd_sig_poll_fd ;
211+ poll_fds [1 ].events = POLLIN ;
212+
213+ while (poll (poll_fds , ARRAY_SIZE (poll_fds ), -1 ) >= 0 ) {
214+ if (poll_fds [1 ].revents )
215+ /* exit signal received */
181216 break ;
217+
218+ if (poll_fds [0 ].revents ) {
219+ err = nl_recvmsgs_default (tlshd_notification_nls );
220+ if (err < 0 ) {
221+ tlshd_log_nl_error ("nl_recvmsgs" , err );
222+ break ;
223+ }
182224 }
183225 };
184226
227+ close (tlshd_sig_poll_fd );
228+
185229out_close :
186230 tlshd_genl_sock_close (tlshd_notification_nls );
187231}
0 commit comments