apply post-1.13.0 patches
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 29 Nov 2008 06:49:36 +0000 (06:49 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 29 Nov 2008 06:49:36 +0000 (06:49 -0000)
coreutils/id.c
init/init.c
libbb/getopt32.c
libbb/lineedit.c
miscutils/inotifyd.c
modutils/modprobe-small.c
modutils/modutils-24.c
shell/ash.c
sysklogd/klogd.c

index a75c226ef9772e31315ee832e1b8dd131809ce02..6ddb2366646e19fa7cdafd773cc821b608bde35e 100644 (file)
 
 #include "libbb.h"
 
+#if !ENABLE_USE_BB_PWD_GRP
+#if defined(__UCLIBC_MAJOR__) && (__UCLIBC_MAJOR__ == 0)
+#if (__UCLIBC_MINOR__ < 9) || (__UCLIBC_MINOR__ == 9 &&  __UCLIBC_SUBLEVEL__ < 30)
+#error "Sorry, you need at least uClibc version 0.9.30 for id applet to build"
+#endif
+#endif
+#endif
+
 enum {
        PRINT_REAL      = (1 << 0),
        NAME_NOT_NUMBER = (1 << 1),
index ef387819c3604f59645cc1ddd7c6ec3d8efda6f8..1caf45b8d40e51803ec0d92350bd9e7ff1a37874 100644 (file)
@@ -209,8 +209,9 @@ static void console_init(void)
                /* Make sure fd 0,1,2 are not closed
                 * (so that they won't be used by future opens) */
                bb_sanitize_stdio();
-               /* Make sure init can't be blocked by writing to stderr */
-               fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK);
+// Users report problems
+//             /* Make sure init can't be blocked by writing to stderr */
+//             fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK);
        }
 
        s = getenv("TERM");
index 49fb5335d2bc74a8f96b481ee16d3ed167d019b2..17babcd65cc4a6b9def4a001e4deae53805eacf4 100644 (file)
@@ -515,6 +515,19 @@ getopt32(char **argv, const char *applet_opts, ...)
                }
        }
 
+       /* In case getopt32 was already called:
+        * reset the libc getopt() function, which keeps internal state.
+        * run_nofork_applet_prime() does this, but we might end up here
+        * also via gunzip_main() -> gzip_main(). Play safe.
+        */
+#ifdef __GLIBC__
+       optind = 0;
+#else /* BSD style */
+       optind = 1;
+       /* optreset = 1; */
+#endif
+       /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */
+
        pargv = NULL;
 
        /* Note: just "getopt() <= 0" will not work well for
index 3953cc904b7f364375847e1b5907cd20de1c7811..0be32550766445b12774f48811c7651e65b4f593 100644 (file)
@@ -1415,8 +1415,10 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
        if ((state->flags & SAVE_HISTORY) && state->hist_file)
                load_history(state->hist_file);
 #endif
+#if MAX_HISTORY > 0
        if (state->flags & DO_HISTORY)
                state->cur_history = state->cnt_history;
+#endif
 
        /* prepare before init handlers */
        cmdedit_y = 0;  /* quasireal y, not true if line > xt*yt */
index 5ac47386addad5d972b224f825d1e861b729b64b..0c4b067846186aa14ad4ecf4bebd035e7a82d32e 100644 (file)
@@ -51,6 +51,7 @@ extern int inotify_add_watch(int fd, const char *path, uint32_t mask);
 int inotifyd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int inotifyd_main(int argc UNUSED_PARAM, char **argv)
 {
+       int n;
        unsigned mask = IN_ALL_EVENTS; // assume we want all events
        struct pollfd pfd;
        char **watched = ++argv; // watched name list
@@ -69,7 +70,6 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv)
        while (*++argv) {
                char *path = *argv;
                char *masks = strchr(path, ':');
-               int wd; // watch descriptor
                // if mask is specified ->
                if (masks) {
                        *masks = '\0'; // split path and mask
@@ -83,32 +83,39 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv)
                        }
                }
                // add watch
-               wd = inotify_add_watch(pfd.fd, path, mask);
-               if (wd < 0) {
+               n = inotify_add_watch(pfd.fd, path, mask);
+               if (n < 0)
                        bb_perror_msg_and_die("add watch (%s) failed", path);
-//             } else {
-//                     bb_error_msg("added %d [%s]:%4X", wd, path, mask);
-               }
+               //bb_error_msg("added %d [%s]:%4X", n, path, mask);
        }
 
        // setup signals
-       bb_signals(0
-               + (1 << SIGHUP)
-               + (1 << SIGINT)
-               + (1 << SIGTERM)
-               + (1 << SIGPIPE)
-               , record_signo);
+       bb_signals(BB_FATAL_SIGS, record_signo);
 
        // do watch
-
-//     pfd.fd = fd;
        pfd.events = POLLIN;
-
-       while (!bb_got_signal && poll(&pfd, 1, -1) > 0) {
+       while (1) {
                ssize_t len;
                void *buf;
                struct inotify_event *ie;
 
+ again:
+               if (bb_got_signal)
+                       break;
+               n = poll(&pfd, 1, -1);
+               /* Signal interrupted us? */
+               if (n < 0 && errno == EINTR)
+                       goto again;
+               // Under Linux, above if() is not necessary.
+               // Non-fatal signals, e.g. SIGCHLD, when set to SIG_DFL,
+               // are not interrupting poll().
+               // Thus we can just break if n <= 0 (see below),
+               // because EINTR will happen only on SIGTERM et al.
+               // But this might be not true under other Unixes,
+               // and is generally way too subtle to depend on.
+               if (n <= 0) // strange error?
+                       break;
+
                // read out all pending events
                xioctl(pfd.fd, FIONREAD, &len);
 #define eventbuf bb_common_bufsiz1
@@ -117,21 +124,21 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv)
                // process events. N.B. events may vary in length
                while (len > 0) {
                        int i;
-                       char events[12];
+                       char events[sizeof(mask_names)];
                        char *s = events;
                        unsigned m = ie->mask;
 
-                       for (i = 0; i < 12; ++i, m >>= 1) {
-                               if (m & 1) {
+                       for (i = 0; i < sizeof(mask_names)-1; ++i, m >>= 1) {
+                               if (m & 1)
                                        *s++ = mask_names[i];
-                               }
                        }
                        *s = '\0';
-//                     bb_error_msg("exec %s %08X\t%s\t%s\t%s", agent, ie->mask, events, watched[ie->wd], ie->len ? ie->name : "");
+                       //bb_error_msg("exec %s %08X\t%s\t%s\t%s", agent,
+                       // ie->mask, events, watched[ie->wd], ie->len ? ie->name : "");
                        args[1] = events;
                        args[2] = watched[ie->wd];
                        args[3] = ie->len ? ie->name : NULL;
-                       xspawn((char **)args);
+                       wait4pid(xspawn((char **)args));
                        // next event
                        i = sizeof(struct inotify_event) + ie->len;
                        len -= i;
index 96a0a08ed1fa3893723f5c94b36a7cfc39c5a20c..d3fde0e8bbafa18c654c11a0be8d75d7d6ccbd4f 100644 (file)
@@ -600,18 +600,22 @@ static void process_module(char *name, const char *cmdline_options)
        free(deps);
 
        /* modprobe -> load it */
-       if (!is_rmmod && (options && !strstr(options, "blacklist"))) {
-               errno = 0;
-               if (load_module(info->pathname, options) != 0) {
-                       if (EEXIST != errno) {
-                               bb_error_msg("'%s': %s",
+       if (!is_rmmod) {
+               if (!options || strstr(options, "blacklist") == NULL) {
+                       errno = 0;
+                       if (load_module(info->pathname, options) != 0) {
+                               if (EEXIST != errno) {
+                                       bb_error_msg("'%s': %s",
                                                info->pathname,
                                                moderror(errno));
-                       } else {
-                               dbg1_error_msg("'%s': %s",
+                               } else {
+                                       dbg1_error_msg("'%s': %s",
                                                info->pathname,
                                                moderror(errno));
+                               }
                        }
+               } else {
+                       dbg1_error_msg("'%s': blacklisted", info->pathname);
                }
        }
  ret:
index 2bc4bda923f4b926b2dc87621c52692c215035e7..c6e7226cd0600631aa9222a12d85905ee7b40ad0 100644 (file)
@@ -3236,8 +3236,10 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM)
        }
 
        shnum = f->header.e_shnum;
-       f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
-       memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
+       /* Growth of ->sections vector will be done by
+        * xrealloc_vector(..., 2, ...), therefore we must allocate
+        * at least 2^2 = 4 extra elements here. */
+       f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
 
        section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
        fseek(fp, f->header.e_shoff, SEEK_SET);
index 92aa5ecc0095027944504d59ab9d125c806dd763..d6fd3884913723146205a2d1a16d834dcb864299 100644 (file)
@@ -536,6 +536,7 @@ static const char dolatstr[] ALIGN1 = {
 #define NHERE    24
 #define NXHERE   25
 #define NNOT     26
+#define N_NUMBER 27
 
 union node;
 
@@ -7546,43 +7547,46 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
 
 /* ============ eval.c */
 
-static int funcblocksize;          /* size of structures in function */
-static int funcstringsize;         /* size of strings in node */
-static void *funcblock;            /* block to allocate function from */
-static char *funcstring;           /* block to allocate strings from */
+static int funcblocksize;       /* size of structures in function */
+static int funcstringsize;      /* size of strings in node */
+static void *funcblock;         /* block to allocate function from */
+static char *funcstring;        /* block to allocate strings from */
 
 /* flags in argument to evaltree */
-#define EV_EXIT 01              /* exit after evaluating tree */
-#define EV_TESTED 02            /* exit status is checked; ignore -e flag */
+#define EV_EXIT    01           /* exit after evaluating tree */
+#define EV_TESTED  02           /* exit status is checked; ignore -e flag */
 #define EV_BACKCMD 04           /* command executing within back quotes */
 
-static const short nodesize[26] = {
-       SHELL_ALIGN(sizeof(struct ncmd)),
-       SHELL_ALIGN(sizeof(struct npipe)),
-       SHELL_ALIGN(sizeof(struct nredir)),
-       SHELL_ALIGN(sizeof(struct nredir)),
-       SHELL_ALIGN(sizeof(struct nredir)),
-       SHELL_ALIGN(sizeof(struct nbinary)),
-       SHELL_ALIGN(sizeof(struct nbinary)),
-       SHELL_ALIGN(sizeof(struct nbinary)),
-       SHELL_ALIGN(sizeof(struct nif)),
-       SHELL_ALIGN(sizeof(struct nbinary)),
-       SHELL_ALIGN(sizeof(struct nbinary)),
-       SHELL_ALIGN(sizeof(struct nfor)),
-       SHELL_ALIGN(sizeof(struct ncase)),
-       SHELL_ALIGN(sizeof(struct nclist)),
-       SHELL_ALIGN(sizeof(struct narg)),
-       SHELL_ALIGN(sizeof(struct narg)),
-       SHELL_ALIGN(sizeof(struct nfile)),
-       SHELL_ALIGN(sizeof(struct nfile)),
-       SHELL_ALIGN(sizeof(struct nfile)),
-       SHELL_ALIGN(sizeof(struct nfile)),
-       SHELL_ALIGN(sizeof(struct nfile)),
-       SHELL_ALIGN(sizeof(struct ndup)),
-       SHELL_ALIGN(sizeof(struct ndup)),
-       SHELL_ALIGN(sizeof(struct nhere)),
-       SHELL_ALIGN(sizeof(struct nhere)),
-       SHELL_ALIGN(sizeof(struct nnot)),
+static const short nodesize[N_NUMBER] = {
+       [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
+       [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
+       [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
+       [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
+       [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
+       [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
+       [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
+       [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
+       [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
+       [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
+       [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
+       [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
+       [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
+       [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
+       [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
+       [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
+       [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
+#if ENABLE_ASH_BASH_COMPAT
+       [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
+#endif
+       [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
+       [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
+       [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
+       [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
+       [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
+       [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
+       [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
+       [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
+       [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
 };
 
 static void calcsize(union node *n);
@@ -9065,8 +9069,6 @@ breakcmd(int argc UNUSED_PARAM, char **argv)
  * This implements the input routines used by the parser.
  */
 
-#define EOF_NLEFT -99           /* value of parsenleft when EOF pushed back */
-
 enum {
        INPUT_PUSH_FILE = 1,
        INPUT_NOFILE_OK = 2,
@@ -9107,7 +9109,6 @@ popstring(void)
 #endif
        parsenextc = sp->prevstring;
        parsenleft = sp->prevnleft;
-/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
        g_parsefile->strpush = sp->prev;
        if (sp != &(g_parsefile->basestrpush))
                free(sp);
@@ -9123,7 +9124,7 @@ preadfd(void)
 
 #if ENABLE_FEATURE_EDITING
  retry:
-       if (!iflag || g_parsefile->fd)
+       if (!iflag || g_parsefile->fd != STDIN_FILENO)
                nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1);
        else {
 #if ENABLE_FEATURE_TAB_COMPLETION
@@ -9171,55 +9172,76 @@ preadfd(void)
  * Refill the input buffer and return the next input character:
  *
  * 1) If a string was pushed back on the input, pop it;
- * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
+ * 2) If an EOF was pushed back (parsenleft < -BIGNUM) or we are reading
  *    from a string so we can't refill the buffer, return EOF.
  * 3) If the is more stuff in this buffer, use it else call read to fill it.
  * 4) Process input up to the next newline, deleting nul characters.
  */
+//#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
+#define pgetc_debug(...) ((void)0)
 static int
 preadbuffer(void)
 {
        char *q;
        int more;
-       char savec;
 
        while (g_parsefile->strpush) {
 #if ENABLE_ASH_ALIAS
-               if (parsenleft == -1 && g_parsefile->strpush->ap &&
-                       parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
+               if (parsenleft == -1 && g_parsefile->strpush->ap
+                && parsenextc[-1] != ' ' && parsenextc[-1] != '\t'
+               ) {
+                       pgetc_debug("preadbuffer PEOA");
                        return PEOA;
                }
 #endif
                popstring();
+               /* try "pgetc" now: */
+               pgetc_debug("internal pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
                if (--parsenleft >= 0)
                        return signed_char2int(*parsenextc++);
        }
-       if (parsenleft == EOF_NLEFT || g_parsefile->buf == NULL)
+       /* on both branches above parsenleft < 0.
+        * "pgetc" needs refilling.
+        */
+
+       /* -90 is -BIGNUM. Below we use -99 to mark "EOF on read",
+        * pungetc() may decrement it a few times. -90 is enough.
+        */
+       if (parsenleft < -90 || g_parsefile->buf == NULL) {
+               pgetc_debug("preadbuffer PEOF1");
+               /* even in failure keep them in lock step,
+                * for correct pungetc. */
+               parsenextc++;
                return PEOF;
-       flush_stdout_stderr();
+       }
 
        more = parselleft;
        if (more <= 0) {
+               flush_stdout_stderr();
  again:
                more = preadfd();
                if (more <= 0) {
-                       parselleft = parsenleft = EOF_NLEFT;
+                       parselleft = parsenleft = -99;
+                       pgetc_debug("preadbuffer PEOF2");
+                       parsenextc++;
                        return PEOF;
                }
        }
 
+       /* Find out where's the end of line.
+        * Set parsenleft/parselleft acordingly.
+        * NUL chars are deleted.
+        */
        q = parsenextc;
-
-       /* delete nul characters */
        for (;;) {
-               int c;
+               char c;
 
                more--;
-               c = *q;
 
-               if (!c)
+               c = *q;
+               if (c == '\0') {
                        memmove(q, q + 1, more);
-               else {
+               else {
                        q++;
                        if (c == '\n') {
                                parsenleft = q - parsenextc - 1;
@@ -9236,22 +9258,23 @@ preadbuffer(void)
        }
        parselleft = more;
 
-       savec = *q;
-       *q = '\0';
-
        if (vflag) {
+               char save = *q;
+               *q = '\0';
                out2str(parsenextc);
+               *q = save;
        }
 
-       *q = savec;
-
+       pgetc_debug("preadbuffer at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
        return signed_char2int(*parsenextc++);
 }
 
 #define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer())
+
 static int
 pgetc(void)
 {
+       pgetc_debug("pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
        return pgetc_as_macro();
 }
 
@@ -9312,6 +9335,7 @@ pungetc(void)
 {
        parsenleft++;
        parsenextc--;
+       pgetc_debug("pushed back to %d:%p'%s'", parsenleft, parsenextc, parsenextc);
 }
 
 /*
@@ -9325,16 +9349,17 @@ static void
 pushstring(char *s, struct alias *ap)
 {
        struct strpush *sp;
-       size_t len;
+       int len;
 
        len = strlen(s);
        INT_OFF;
        if (g_parsefile->strpush) {
-               sp = ckzalloc(sizeof(struct strpush));
+               sp = ckzalloc(sizeof(*sp));
                sp->prev = g_parsefile->strpush;
-               g_parsefile->strpush = sp;
-       } else
-               sp = g_parsefile->strpush = &(g_parsefile->basestrpush);
+       } else {
+               sp = &(g_parsefile->basestrpush);
+       }
+       g_parsefile->strpush = sp;
        sp->prevstring = parsenextc;
        sp->prevnleft = parsenleft;
 #if ENABLE_ASH_ALIAS
@@ -9424,7 +9449,7 @@ setinputfd(int fd, int push)
        close_on_exec_on(fd);
        if (push) {
                pushfile();
-               g_parsefile->buf = 0;
+               g_parsefile->buf = NULL;
        }
        g_parsefile->fd = fd;
        if (g_parsefile->buf == NULL)
index 723ca80677358de428ac7f166367fa7bae454414..a27ddf4f4b6688babf16e1a594810ecf8eba5de8 100644 (file)
@@ -73,9 +73,6 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
 
        syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
 
-       /* Initially null terminate the buffer in case of a very long line */
-       log_buffer[KLOGD_LOGBUF_SIZE - 1] = '\0';
-
        while (1) {
                int n;
                int priority;
@@ -89,6 +86,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
                                        errno);
                        break;
                }
+               log_buffer[used + n] = '\0';
 
                /* klogctl buffer parsing modelled after code in dmesg.c */
                start = &log_buffer[0];
@@ -101,7 +99,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
                                /* This line is incomplete... */
                                if (start != log_buffer) {
                                        /* move it to the front of the buffer */
-                                       strcpy(log_buffer, start);
+                                       overlapping_strcpy(log_buffer, start);
                                        /* don't log it yet */
                                        used = strlen(log_buffer);
                                        break;