aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Denis Vlasenko <vda.linux@googlemail.com>2008-11-29 06:49:36 +0000
committerGravatar Denis Vlasenko <vda.linux@googlemail.com>2008-11-29 06:49:36 +0000
commitab310e1b1c2f85235e61c471802b53314da919f0 (patch)
tree415cf40159a0c2b6009a27df18b0cc45bea2e956
parent1cd1012a9063656a6b5b75dac8d400abd60cd643 (diff)
downloadbusybox-ab310e1b1c2f85235e61c471802b53314da919f0.tar.gz
busybox-ab310e1b1c2f85235e61c471802b53314da919f0.tar.bz2
apply post-1.13.0 patches
-rw-r--r--coreutils/id.c8
-rw-r--r--init/init.c5
-rw-r--r--libbb/getopt32.c13
-rw-r--r--libbb/lineedit.c2
-rw-r--r--miscutils/inotifyd.c51
-rw-r--r--modutils/modprobe-small.c18
-rw-r--r--modutils/modutils-24.c6
-rw-r--r--shell/ash.c147
-rw-r--r--sysklogd/klogd.c6
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;