From 517413f9affae582f5e824ef45805662d676be6a Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 10 Dec 2008 11:16:47 +0000 Subject: [PATCH] bb_info_msg: make it do atomic, unbuffered writes udhcpc: fix a problem where we don't open listening socket fast enough function old new delta bb_info_msg 70 126 +56 change_listen_mode 37 78 +41 udhcp_listen_socket 151 124 -27 udhcpc_main 2344 2285 -59 --- libbb/info_msg.c | 26 ++++++++++++++++++++++++++ networking/udhcp/dhcpc.c | 23 ++++++++++++++++------- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/libbb/info_msg.c b/libbb/info_msg.c index ffef05e54..8b8a1fcca 100644 --- a/libbb/info_msg.c +++ b/libbb/info_msg.c @@ -12,6 +12,7 @@ void FAST_FUNC bb_info_msg(const char *s, ...) { +#ifdef THIS_ONE_DOESNT_DO_SINGLE_WRITE va_list p; /* va_copy is used because it is not portable * to use va_list p twice */ @@ -27,4 +28,29 @@ void FAST_FUNC bb_info_msg(const char *s, ...) vsyslog(LOG_INFO, s, p2); va_end(p2); va_end(p); +#else + int used; + char *msg; + va_list p; + + if (logmode == 0) + return; + + va_start(p, s); + used = vasprintf(&msg, s, p); + if (used < 0) + return; + + if (ENABLE_FEATURE_SYSLOG && (logmode & LOGMODE_SYSLOG)) + syslog(LOG_INFO, "%s", msg); + if (logmode & LOGMODE_STDIO) { + fflush(stdout); + /* used = strlen(msg); - must be true already */ + msg[used++] = '\n'; + full_write(STDOUT_FILENO, msg, used); + } + + free(msg); + va_end(p); +#endif } diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index e2e5b0a82..115cddbf0 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -43,11 +43,17 @@ static void change_listen_mode(int new_mode) { DEBUG("entering %s listen mode", new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none"); + + listen_mode = new_mode; if (sockfd >= 0) { close(sockfd); sockfd = -1; } - listen_mode = new_mode; + if (new_mode == LISTEN_KERNEL) + sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); + else if (new_mode != LISTEN_NONE) + sockfd = udhcp_raw_socket(client_config.ifindex); + /* else LISTEN_NONE: sockfd stay closed */ } @@ -320,12 +326,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) for (;;) { unsigned timestamp_before_wait; - if (listen_mode != LISTEN_NONE && sockfd < 0) { - if (listen_mode == LISTEN_KERNEL) - sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); - else - sockfd = udhcp_raw_socket(client_config.ifindex); - } + //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); + + /* Was opening raw or udp socket here + * if (listen_mode != LISTEN_NONE && sockfd < 0), + * but on fast network renew responses return faster + * than we open sockets. Thus this code is moved + * to change_listen_mode(). Thus we open listen socket + * BEFORE we send renew request (see "case BOUND:"). */ + max_fd = udhcp_sp_fd_set(&rfds, sockfd); tv.tv_sec = timeout - already_waited_sec;