summaryrefslogtreecommitdiffhomepage
path: root/networking/udhcp/dhcpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpd.c')
-rw-r--r--networking/udhcp/dhcpd.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 093239536..db3ab4f00 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -915,20 +915,18 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
udhcp_sp_fd_set(pfds, server_socket);
tv = timeout_end - monotonic_sec();
- retval = 0;
- if (!server_config.auto_time || tv > 0) {
- retval = poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1);
- }
- if (retval == 0) {
- write_leases();
- goto continue_with_autotime;
- }
- if (retval < 0 && errno != EINTR) {
- log1("error on select");
- continue;
+ /* Block here waiting for either signal or packet */
+ retval = safe_poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1);
+ if (retval <= 0) {
+ if (retval == 0) {
+ write_leases();
+ goto continue_with_autotime;
+ }
+ /* < 0 and not EINTR: should not happen */
+ bb_perror_msg_and_die("poll");
}
- switch (udhcp_sp_read(pfds)) {
+ if (pfds[0].revents) switch (udhcp_sp_read()) {
case SIGUSR1:
bb_error_msg("received %s", "SIGUSR1");
write_leases();
@@ -938,12 +936,16 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
bb_error_msg("received %s", "SIGTERM");
write_leases();
goto ret0;
- case 0: /* no signal: read a packet */
- break;
- default: /* signal or error (probably EINTR): back to select */
- continue;
}
+ /* Is it a packet? */
+ if (!pfds[1].revents)
+ continue; /* no */
+
+ /* Note: we do not block here, we block on poll() instead.
+ * Blocking here would prevent SIGTERM from working:
+ * socket read inside this call is restarted on caught signals.
+ */
bytes = udhcp_recv_kernel_packet(&packet, server_socket);
if (bytes < 0) {
/* bytes can also be -2 ("bad packet data") */