udhcpc: fix a read error loop (e.g.: device is down) blocking TERM
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
d30b89c7ee
commit
4248c33a85
@ -307,7 +307,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
||||
/* Goes to stdout (unless NOMMU) and possibly syslog */
|
||||
bb_info_msg("%s (v"BB_VER") started", applet_name);
|
||||
|
||||
/* if not set, and not suppressed, setup the default client ID */
|
||||
/* If not set, and not suppressed, set up the default client ID */
|
||||
if (!client_config.clientid && !(opt & OPT_C)) {
|
||||
client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
|
||||
client_config.clientid[OPT_DATA] = 1;
|
||||
@ -317,7 +317,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
||||
if (!client_config.vendorclass)
|
||||
client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, "udhcp "BB_VER, 0);
|
||||
|
||||
/* setup the signal pipe */
|
||||
/* Set up the signal pipe */
|
||||
udhcp_sp_setup();
|
||||
|
||||
state = INIT_SELECTING;
|
||||
@ -467,19 +467,45 @@ 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 */
|
||||
|
||||
/* select() didn't timeout, something happened */
|
||||
|
||||
/* Is it a signal? */
|
||||
/* note: udhcp_sp_read checks FD_ISSET before reading */
|
||||
switch (udhcp_sp_read(&rfds)) {
|
||||
case SIGUSR1:
|
||||
perform_renew();
|
||||
/* Start things over */
|
||||
packet_num = 0;
|
||||
/* Kill any timeouts because the user wants this to hurry along */
|
||||
timeout = 0;
|
||||
continue;
|
||||
case SIGUSR2:
|
||||
perform_release(requested_ip, server_addr);
|
||||
timeout = INT_MAX;
|
||||
continue;
|
||||
case SIGTERM:
|
||||
bb_info_msg("Received SIGTERM");
|
||||
if (opt & OPT_R) /* release on quit */
|
||||
perform_release(requested_ip, server_addr);
|
||||
goto ret0;
|
||||
}
|
||||
|
||||
/* select() didn't timeout, something did happen. */
|
||||
/* Is it a packet? */
|
||||
if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
|
||||
int len;
|
||||
/* A packet is ready, read it */
|
||||
if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds))
|
||||
continue; /* no */
|
||||
|
||||
{
|
||||
int len;
|
||||
|
||||
/* A packet is ready, read it */
|
||||
if (listen_mode == LISTEN_KERNEL)
|
||||
len = udhcp_recv_kernel_packet(&packet, sockfd);
|
||||
else
|
||||
len = udhcp_recv_raw_packet(&packet, sockfd);
|
||||
if (len == -1) { /* error is severe, reopen socket */
|
||||
if (len == -1) {
|
||||
/* Error is severe, reopen socket */
|
||||
bb_info_msg("Read error: %s, reopening socket", strerror(errno));
|
||||
sleep(discover_timeout); /* 3 seconds by default */
|
||||
change_listen_mode(listen_mode); /* just close and reopen */
|
||||
@ -490,6 +516,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
||||
already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
|
||||
if (len < 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (packet.xid != xid) {
|
||||
log1("xid %x (our is %x), ignoring packet",
|
||||
@ -629,34 +656,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
||||
already_waited_sec = 0;
|
||||
}
|
||||
continue;
|
||||
/* case BOUND, RELEASED: - ignore all packets */
|
||||
}
|
||||
continue; /* back to main loop */
|
||||
}
|
||||
|
||||
/* select() didn't timeout, something did happen.
|
||||
* But it wasn't a packet. It's a signal pipe then. */
|
||||
{
|
||||
int signo = udhcp_sp_read(&rfds);
|
||||
switch (signo) {
|
||||
case SIGUSR1:
|
||||
perform_renew();
|
||||
/* start things over */
|
||||
packet_num = 0;
|
||||
/* Kill any timeouts because the user wants this to hurry along */
|
||||
timeout = 0;
|
||||
break;
|
||||
case SIGUSR2:
|
||||
perform_release(requested_ip, server_addr);
|
||||
timeout = INT_MAX;
|
||||
break;
|
||||
case SIGTERM:
|
||||
bb_info_msg("Received SIGTERM");
|
||||
if (opt & OPT_R) /* release on quit */
|
||||
perform_release(requested_ip, server_addr);
|
||||
goto ret0;
|
||||
}
|
||||
/* case BOUND: - ignore all packets */
|
||||
/* case RELEASED: - ignore all packets */
|
||||
}
|
||||
/* back to main loop */
|
||||
} /* for (;;) - main loop ends */
|
||||
|
||||
ret0:
|
||||
|
Loading…
Reference in New Issue
Block a user