From ab310e1b1c2f85235e61c471802b53314da919f0 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 29 Nov 2008 06:49:36 +0000 Subject: [PATCH] apply post-1.13.0 patches --- coreutils/id.c | 8 +++ init/init.c | 5 +- libbb/getopt32.c | 13 ++++ libbb/lineedit.c | 2 + miscutils/inotifyd.c | 51 +++++++------ modutils/modprobe-small.c | 18 +++-- modutils/modutils-24.c | 6 +- shell/ash.c | 147 ++++++++++++++++++++++---------------- sysklogd/klogd.c | 6 +- 9 files changed, 158 insertions(+), 98 deletions(-) diff --git a/coreutils/id.c b/coreutils/id.c index a75c226ef..6ddb23666 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -17,6 +17,14 @@ #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), diff --git a/init/init.c b/init/init.c index ef387819c..1caf45b8d 100644 --- a/init/init.c +++ b/init/init.c @@ -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"); diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 49fb5335d..17babcd65 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -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 diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 3953cc904..0be325507 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -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 */ diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 5ac47386a..0c4b06784 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -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; diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 96a0a08ed..d3fde0e8b 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -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: diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c index 2bc4bda92..c6e7226cd 100644 --- a/modutils/modutils-24.c +++ b/modutils/modutils-24.c @@ -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); diff --git a/shell/ash.c b/shell/ash.c index 92aa5ecc0..d6fd38849 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -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) diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 723ca8067..a27ddf4f4 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -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; -- 2.25.1