summaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp')
-rw-r--r--networking/udhcp/common.h2
-rw-r--r--networking/udhcp/d6_dhcpc.c9
-rw-r--r--networking/udhcp/dhcpc.c9
-rw-r--r--networking/udhcp/dhcpd.c34
-rw-r--r--networking/udhcp/signalpipe.c11
5 files changed, 33 insertions, 32 deletions
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 04939e7..13059f1 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -314,7 +314,7 @@ int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
void udhcp_sp_setup(void) FAST_FUNC;
void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC;
-int udhcp_sp_read(struct pollfd *pfds) FAST_FUNC;
+int udhcp_sp_read(void) FAST_FUNC;
int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC;
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 35c99e8..289df66 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -1375,13 +1375,12 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* yah, I know, *you* say it would never happen */
timeout = INT_MAX;
continue; /* back to main loop */
- } /* if select timed out */
+ } /* if poll timed out */
- /* select() didn't timeout, something happened */
+ /* poll() didn't timeout, something happened */
/* Is it a signal? */
- /* note: udhcp_sp_read checks poll result before reading */
- switch (udhcp_sp_read(pfds)) {
+ switch (udhcp_sp_read()) {
case SIGUSR1:
client_config.first_secs = 0; /* make secs field count from 0 */
already_waited_sec = 0;
@@ -1416,7 +1415,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
}
/* Is it a packet? */
- if (listen_mode == LISTEN_NONE || !pfds[1].revents)
+ if (!pfds[1].revents)
continue; /* no */
{
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 35694fb..90b07bf 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1574,13 +1574,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* yah, I know, *you* say it would never happen */
timeout = INT_MAX;
continue; /* back to main loop */
- } /* if select timed out */
+ } /* if poll timed out */
- /* select() didn't timeout, something happened */
+ /* poll() didn't timeout, something happened */
/* Is it a signal? */
- /* note: udhcp_sp_read checks poll result before reading */
- switch (udhcp_sp_read(pfds)) {
+ switch (udhcp_sp_read()) {
case SIGUSR1:
client_config.first_secs = 0; /* make secs field count from 0 */
already_waited_sec = 0;
@@ -1615,7 +1614,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
}
/* Is it a packet? */
- if (listen_mode == LISTEN_NONE || !pfds[1].revents)
+ if (!pfds[1].revents)
continue; /* no */
{
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 0932395..db3ab4f 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") */
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
index b101b4c..2ff78f0 100644
--- a/networking/udhcp/signalpipe.c
+++ b/networking/udhcp/signalpipe.c
@@ -40,6 +40,7 @@ void FAST_FUNC udhcp_sp_setup(void)
xpiped_pair(signal_pipe);
close_on_exec_on(signal_pipe.rd);
close_on_exec_on(signal_pipe.wr);
+ ndelay_on(signal_pipe.rd);
ndelay_on(signal_pipe.wr);
bb_signals(0
+ (1 << SIGUSR1)
@@ -61,20 +62,20 @@ void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd)
pfds[1].fd = extra_fd;
pfds[1].events = POLLIN;
}
+ /* this simplifies "is extra_fd ready?" tests elsewhere: */
+ pfds[1].revents = 0;
}
/* Read a signal from the signal pipe. Returns 0 if there is
* no signal, -1 on error (and sets errno appropriately), and
* your signal on success */
-int FAST_FUNC udhcp_sp_read(struct pollfd pfds[2])
+int FAST_FUNC udhcp_sp_read(void)
{
unsigned char sig;
- if (!pfds[0].revents)
- return 0;
-
+ /* Can't block here, fd is in nonblocking mode */
if (safe_read(signal_pipe.rd, &sig, 1) != 1)
- return -1;
+ return 0;
return sig;
}