Apply post-1.18.3 fixes, bump version to 1.18.4 1_18_4
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 13 Mar 2011 01:39:10 +0000 (02:39 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 13 Mar 2011 01:39:10 +0000 (02:39 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Config.in
Makefile
coreutils/cksum.c
modutils/modutils-24.c
networking/wget.c
scripts/kconfig/mconf.c
sysklogd/klogd.c

index 140572e2d9d7b35f1fe0b72098bb9dfa362c9098..5e31d20c7b3eb8481cc2f39ada3ee72dfeb99d19 100644 (file)
--- a/Config.in
+++ b/Config.in
@@ -126,7 +126,6 @@ config FEATURE_INSTALLER
 config INSTALL_NO_USR
        bool "Don't use /usr"
        default n
-       depends on FEATURE_INSTALLER
        help
          Disable use of /usr. busybox --install and "make install"
          will install applets only to /bin and /sbin,
index 656ee2c79f00fe86f6dbe0e4d0b3bccbd5682c07..cb0e3e4346f71c9f57394c112ce68c972584af4a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 18
-SUBLEVEL = 3
+SUBLEVEL = 4
 EXTRAVERSION =
 NAME = Unnamed
 
index 7a37e6add62d569622b871c5f31b90e1175f4f74..53fb87a78c8fbee04471977aac6d8ef462feec13 100644 (file)
@@ -38,6 +38,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
 
 #define read_buf bb_common_bufsiz1
                while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) {
+                       length += bytes_read;
                        crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table);
                }
                close(fd);
index 2b34954c0f269bce4c8834ab85434e59817a308c..bd650cab5448f4ac4bc8f573139367cb99e9b725 100644 (file)
@@ -2474,6 +2474,7 @@ new_process_module_arguments(struct obj_file *f, const char *options)
                n = 0;
                p = val;
                while (*p != 0) {
+                       char sv_ch;
                        char *endp;
 
                        if (++n > max)
@@ -2482,14 +2483,17 @@ new_process_module_arguments(struct obj_file *f, const char *options)
                        switch (*pinfo) {
                        case 's':
                                len = strcspn(p, ",");
+                               sv_ch = p[len];
                                p[len] = 0;
                                obj_string_patch(f, sym->secidx,
                                                 loc - contents, p);
                                loc += tgt_sizeof_char_p;
                                p += len;
+                               *p = sv_ch;
                                break;
                        case 'c':
                                len = strcspn(p, ",");
+                               sv_ch = p[len];
                                p[len] = 0;
                                if (len >= charssize)
                                        bb_error_msg_and_die("string too long for %s (max %ld)", param,
@@ -2497,6 +2501,7 @@ new_process_module_arguments(struct obj_file *f, const char *options)
                                strcpy((char *) loc, p);
                                loc += charssize;
                                p += len;
+                               *p = sv_ch;
                                break;
                        case 'b':
                                *loc++ = strtoul(p, &endp, 0);
index 0db9b33655a945a53ff92434847f6ab8e71ef319..afe0d3ab768465beb491aef868fa80fd1f6f6495 100644 (file)
@@ -446,7 +446,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
 
 static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
 {
-       char buf[512];
+       char buf[4*1024]; /* made bigger to speed up local xfers */
 #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
 # if ENABLE_FEATURE_WGET_TIMEOUT
        unsigned second_cnt;
@@ -455,7 +455,6 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
 
        polldata.fd = fileno(dfp);
        polldata.events = POLLIN | POLLPRI;
-       ndelay_on(polldata.fd);
 #endif
        progress_meter(PROGRESS_START);
 
@@ -464,6 +463,10 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
 
        /* Loops only if chunked */
        while (1) {
+
+#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
+               ndelay_on(polldata.fd);
+#endif
                while (1) {
                        int n;
                        unsigned rdsz;
@@ -493,22 +496,46 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
                                progress_meter(PROGRESS_BUMP);
                        }
 #endif
+                       /* fread internally uses read loop, which in our case
+                        * is usually exited when we get EAGAIN.
+                        * In this case, libc sets error marker on the stream.
+                        * Need to clear it before next fread to avoid possible
+                        * rare false positive ferror below. Rare because usually
+                        * fread gets more than zero bytes, and we don't fall
+                        * into if (n <= 0) ...
+                        */
+                       clearerr(dfp);
+                       errno = 0;
                        n = safe_fread(buf, rdsz, dfp);
+                       /* man fread:
+                        * If error occurs, or EOF is reached, the return value
+                        * is a short item count (or zero).
+                        * fread does not distinguish between EOF and error.
+                        */
                        if (n <= 0) {
-                               if (ferror(dfp)) {
-                                       /* perror will not work: ferror doesn't set errno */
-                                       bb_error_msg_and_die(bb_msg_read_error);
-                               }
-                               break;
+#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
+                               if (errno == EAGAIN) /* poll lied, there is no data? */
+                                       continue; /* yes */
+#endif
+                               if (ferror(dfp))
+                                       bb_perror_msg_and_die(bb_msg_read_error);
+                               break; /* EOF, not error */
                        }
+
                        xwrite(output_fd, buf, n);
 #if ENABLE_FEATURE_WGET_STATUSBAR
                        G.transferred += n;
                        progress_meter(PROGRESS_BUMP);
 #endif
-                       if (G.got_clen)
+                       if (G.got_clen) {
                                G.content_len -= n;
+                               if (G.content_len == 0)
+                                       break;
+                       }
                }
+#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
+               ndelay_off(polldata.fd);
+#endif
 
                if (!G.chunked)
                        break;
@@ -706,6 +733,11 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
                fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
                        target.host, user_agent);
 
+               /* Ask server to close the connection as soon as we are done
+                * (IOW: we do not intend to send more requests)
+                */
+               fprintf(sfp, "Connection: close\r\n");
+
 #if ENABLE_FEATURE_WGET_AUTHENTICATION
                if (target.user) {
                        fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
@@ -719,22 +751,25 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
 
                if (G.beg_range)
                        fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
+
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS
                if (extra_headers)
                        fputs(extra_headers, sfp);
 
                if (opt & WGET_OPT_POST_DATA) {
                        char *estr = URL_escape(post_data);
-                       fprintf(sfp, "Content-Type: application/x-www-form-urlencoded\r\n");
-                       fprintf(sfp, "Content-Length: %u\r\n" "\r\n" "%s",
-                                       (int) strlen(estr), estr);
-                       /*fprintf(sfp, "Connection: Keep-Alive\r\n\r\n");*/
-                       /*fprintf(sfp, "%s\r\n", estr);*/
+                       fprintf(sfp,
+                               "Content-Type: application/x-www-form-urlencoded\r\n"
+                               "Content-Length: %u\r\n"
+                               "\r\n"
+                               "%s",
+                               (int) strlen(estr), estr
+                       );
                        free(estr);
                } else
 #endif
-               { /* If "Connection:" is needed, document why */
-                       fprintf(sfp, /* "Connection: close\r\n" */ "\r\n");
+               {
+                       fprintf(sfp, "\r\n");
                }
 
                fflush(sfp);
index 0c548bfc01c89a25e6f4c7aadc1fbbf007ed7741..d292b46cc1fcde615294d04df8aa03f4e79e7585 100644 (file)
@@ -256,7 +256,7 @@ search_help[] = N_(
        "          USB$ => find all CONFIG_ symbols ending with USB\n"
        "\n");
 
-static char buf[4096], *bufptr = buf;
+static char buf[4096*10], *bufptr = buf;
 static char input_buf[4096];
 static const char filename[] = ".config";
 static char *args[1024], **argptr = args;
index 0d4c2578d3c5e99edaa0a461418987bdfdec7331..db32065fb252aeba30306d0544cfb2fdb9102e5d 100644 (file)
@@ -150,12 +150,41 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
         */
        klogd_open();
        openlog("kernel", 0, LOG_KERN);
+       /*
+        * glibc problem: for some reason, glibc changes LOG_KERN to LOG_USER
+        * above. The logic behind this is that standard
+        * http://pubs.opengroup.org/onlinepubs/9699919799/functions/syslog.html
+        * says the following about openlog and syslog:
+        * "LOG_USER
+        *  Messages generated by arbitrary processes.
+        *  This is the default facility identifier if none is specified."
+        *
+        * I believe glibc misinterpreted this text as "if openlog's
+        * third parameter is 0 (=LOG_KERN), treat it as LOG_USER".
+        * Whereas it was meant to say "if *syslog* is called with facility
+        * 0 in its 1st parameter without prior call to openlog, then perform
+        * implicit openlog(LOG_USER)".
+        *
+        * As a result of this, eh, feature, standard klogd was forced
+        * to open-code its own openlog and syslog implementation (!).
+        *
+        * Note that prohibiting openlog(LOG_KERN) on libc level does not
+        * add any security: any process can open a socket to "/dev/log"
+        * and write a string "<0>Voila, a LOG_KERN + LOG_EMERG message"
+        *
+        * Google code search tells me there is no widespread use of
+        * openlog("foo", 0, 0), thus fixing glibc won't break userspace.
+        *
+        * The bug against glibc was filed:
+        * bugzilla.redhat.com/show_bug.cgi?id=547000
+        */
 
        if (i)
                klogd_setloglevel(i);
 
-       bb_signals(BB_FATAL_SIGS, record_signo);
        signal(SIGHUP, SIG_IGN);
+       /* We want klogd_read to not be restarted, thus _norestart: */
+       bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo);
 
        syslog(LOG_NOTICE, "klogd started: %s", bb_banner);