From vda at busybox.net Tue May 1 13:07:33 2007 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 May 2007 13:07:33 -0700 (PDT) Subject: svn commit: trunk/busybox: coreutils libbb procps Message-ID: <20070501200733.8A13B4859E@busybox.net> Author: vda Date: 2007-05-01 13:07:29 -0700 (Tue, 01 May 2007) New Revision: 18534 Log: test: code size saving, no logic changes ps: fix warning, make a bit smaller kill -l: make smaller & know much more signals function old new delta get_signum 121 153 +32 kill_main 826 843 +17 get_signame 44 36 -8 signals 252 224 -28 .rodata 131955 131923 -32 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/3 up/down: 49/-68) Total: -19 bytes Modified: trunk/busybox/coreutils/test.c trunk/busybox/libbb/u_signal_names.c trunk/busybox/procps/kill.c trunk/busybox/procps/ps.c Changeset: Modified: trunk/busybox/coreutils/test.c =================================================================== --- trunk/busybox/coreutils/test.c 2007-04-30 21:23:22 UTC (rev 18533) +++ trunk/busybox/coreutils/test.c 2007-05-01 20:07:29 UTC (rev 18534) @@ -85,12 +85,12 @@ RPAREN, OPERAND }; -#define __is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5) -#define __is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5) -#define __is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2) -#define __is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2) -#define __is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5) -#define __is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2) +#define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5) +#define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5) +#define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2) +#define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2) +#define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5) +#define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2) enum token_types { UNOP, BINOP, @@ -100,64 +100,67 @@ }; static const struct t_op { - const char * const op_text; + char op_text[4]; unsigned char op_num, op_type; } ops[] = { - { - "-r", FILRD, UNOP}, { - "-w", FILWR, UNOP}, { - "-x", FILEX, UNOP}, { - "-e", FILEXIST, UNOP}, { - "-f", FILREG, UNOP}, { - "-d", FILDIR, UNOP}, { - "-c", FILCDEV, UNOP}, { - "-b", FILBDEV, UNOP}, { - "-p", FILFIFO, UNOP}, { - "-u", FILSUID, UNOP}, { - "-g", FILSGID, UNOP}, { - "-k", FILSTCK, UNOP}, { - "-s", FILGZ, UNOP}, { - "-t", FILTT, UNOP}, { - "-z", STREZ, UNOP}, { - "-n", STRNZ, UNOP}, { - "-h", FILSYM, UNOP}, /* for backwards compat */ - { - "-O", FILUID, UNOP}, { - "-G", FILGID, UNOP}, { - "-L", FILSYM, UNOP}, { - "-S", FILSOCK, UNOP}, { - "=", STREQ, BINOP}, { - "==", STREQ, BINOP}, { - "!=", STRNE, BINOP}, { - "<", STRLT, BINOP}, { - ">", STRGT, BINOP}, { - "-eq", INTEQ, BINOP}, { - "-ne", INTNE, BINOP}, { - "-ge", INTGE, BINOP}, { - "-gt", INTGT, BINOP}, { - "-le", INTLE, BINOP}, { - "-lt", INTLT, BINOP}, { - "-nt", FILNT, BINOP}, { - "-ot", FILOT, BINOP}, { - "-ef", FILEQ, BINOP}, { - "!", UNOT, BUNOP}, { - "-a", BAND, BBINOP}, { - "-o", BOR, BBINOP}, { - "(", LPAREN, PAREN}, { - ")", RPAREN, PAREN}, { - 0, 0, 0} + { "-r", FILRD , UNOP }, + { "-w", FILWR , UNOP }, + { "-x", FILEX , UNOP }, + { "-e", FILEXIST, UNOP }, + { "-f", FILREG , UNOP }, + { "-d", FILDIR , UNOP }, + { "-c", FILCDEV , UNOP }, + { "-b", FILBDEV , UNOP }, + { "-p", FILFIFO , UNOP }, + { "-u", FILSUID , UNOP }, + { "-g", FILSGID , UNOP }, + { "-k", FILSTCK , UNOP }, + { "-s", FILGZ , UNOP }, + { "-t", FILTT , UNOP }, + { "-z", STREZ , UNOP }, + { "-n", STRNZ , UNOP }, + { "-h", FILSYM , UNOP }, /* for backwards compat */ + + { "-O" , FILUID , UNOP }, + { "-G" , FILGID , UNOP }, + { "-L" , FILSYM , UNOP }, + { "-S" , FILSOCK, UNOP }, + { "=" , STREQ , BINOP }, + { "==" , STREQ , BINOP }, + { "!=" , STRNE , BINOP }, + { "<" , STRLT , BINOP }, + { ">" , STRGT , BINOP }, + { "-eq", INTEQ , BINOP }, + { "-ne", INTNE , BINOP }, + { "-ge", INTGE , BINOP }, + { "-gt", INTGT , BINOP }, + { "-le", INTLE , BINOP }, + { "-lt", INTLT , BINOP }, + { "-nt", FILNT , BINOP }, + { "-ot", FILOT , BINOP }, + { "-ef", FILEQ , BINOP }, + { "!" , UNOT , BUNOP }, + { "-a" , BAND , BBINOP }, + { "-o" , BOR , BBINOP }, + { "(" , LPAREN , PAREN }, + { ")" , RPAREN , PAREN }, }; -#ifdef CONFIG_FEATURE_TEST_64 +enum { NUM_OPS = sizeof(ops) / sizeof(ops[0]) }; + +#if ENABLE_FEATURE_TEST_64 typedef int64_t arith_t; #else typedef int arith_t; #endif +/* Cannot eliminate these static data (do the G trick) + * because of bb_test usage from other applets */ static char **t_wp; static struct t_op const *t_wp_op; static gid_t *group_array; static int ngroups; +static jmp_buf leaving; static enum token t_lex(char *s); static arith_t oexpr(enum token n); @@ -176,8 +179,6 @@ static int is_a_group_member(gid_t gid); static void initialize_group_array(void); -static jmp_buf leaving; - int bb_test(int argc, char **argv) { int res; @@ -210,7 +211,7 @@ * isn't likely in the case of a shell. paranoia * prevails... */ - ngroups = 0; + ngroups = 0; /* Implement special cases from POSIX.2, section 4.62.4 */ if (argc == 1) @@ -223,8 +224,9 @@ if (argc == 3) return *argv[2] != '\0'; _off = argc - 4; - if (t_lex(argv[2+_off]), t_wp_op && t_wp_op->op_type == BINOP) { - t_wp = &argv[1+_off]; + t_lex(argv[2 + _off]); + if (t_wp_op && t_wp_op->op_type == BINOP) { + t_wp = &argv[1 + _off]; return binop() == 0; } } @@ -238,6 +240,7 @@ return res; } +static void syntax(const char *op, const char *msg) ATTRIBUTE_NORETURN; static void syntax(const char *op, const char *msg) { if (op && *op) { @@ -296,20 +299,20 @@ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); if (n == STREZ) - return strlen(*t_wp) == 0; - else if (n == STRNZ) - return strlen(*t_wp) != 0; - else if (n == FILTT) + return t_wp[0][0] == '\0'; + if (n == STRNZ) + return t_wp[0][0] != '\0'; + if (n == FILTT) return isatty(getn(*t_wp)); - else - return filstat(*t_wp, n); + return filstat(*t_wp, n); } - if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { + t_lex(t_wp[1]); + if (t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } - return strlen(*t_wp) > 0; + return t_wp[0][0] != '\0'; } static int binop(void) @@ -322,10 +325,11 @@ (void) t_lex(*++t_wp); op = t_wp_op; - if ((opnd2 = *++t_wp) == (char *) 0) + opnd2 = *++t_wp; + if (opnd2 == NULL) syntax(op->op_text, "argument expected"); - if (__is_int_op(op->op_num)) { + if (is_int_op(op->op_num)) { val1 = getn(opnd1); val2 = getn(opnd2); if (op->op_num == INTEQ) @@ -341,7 +345,7 @@ if (op->op_num == INTLT) return val1 < val2; } - if (__is_str_op(op->op_num)) { + if (is_str_op(op->op_num)) { val1 = strcmp(opnd1, opnd2); if (op->op_num == STREQ) return val1 == 0; @@ -355,7 +359,7 @@ /* We are sure that these three are by now the only binops we didn't check * yet, so we do not check if the class is correct: */ -/* if (__is_file_op(op->op_num)) */ +/* if (is_file_op(op->op_num)) */ { struct stat b1, b2; @@ -390,7 +394,7 @@ return 0; if (mode == FILEXIST) return 1; - else if (__is_file_access(mode)) { + if (is_file_access(mode)) { if (mode == FILRD) i = R_OK; if (mode == FILWR) @@ -399,7 +403,7 @@ i = X_OK; return test_eaccess(nm, i) == 0; } - else if (__is_file_type(mode)) { + if (is_file_type(mode)) { if (mode == FILREG) i = S_IFREG; if (mode == FILDIR) @@ -422,10 +426,10 @@ return 0; #endif } -filetype: + filetype: return ((s.st_mode & S_IFMT) == i); } - else if (__is_file_bit(mode)) { + if (is_file_bit(mode)) { if (mode == FILSUID) i = S_ISUID; if (mode == FILSGID) @@ -434,33 +438,33 @@ i = S_ISVTX; return ((s.st_mode & i) != 0); } - else if (mode == FILGZ) + if (mode == FILGZ) return s.st_size > 0L; - else if (mode == FILUID) + if (mode == FILUID) return s.st_uid == geteuid(); - else if (mode == FILGID) + if (mode == FILGID) return s.st_gid == getegid(); - else - return 1; /* NOTREACHED */ - + return 1; /* NOTREACHED */ } static enum token t_lex(char *s) { - struct t_op const *op = ops; + const struct t_op *op; - if (s == 0) { - t_wp_op = (struct t_op *) 0; + t_wp_op = NULL; + if (s == NULL) { return EOI; } - while (op->op_text) { + + op = ops; + do { if (strcmp(s, op->op_text) == 0) { t_wp_op = op; return op->op_num; } op++; - } - t_wp_op = (struct t_op *) 0; + } while (op < ops + NUM_OPS); + return OPERAND; } @@ -469,14 +473,14 @@ static arith_t getn(const char *s) { char *p; -#ifdef CONFIG_FEATURE_TEST_64 +#if ENABLE_FEATURE_TEST_64 long long r; #else long r; #endif errno = 0; -#ifdef CONFIG_FEATURE_TEST_64 +#if ENABLE_FEATURE_TEST_64 r = strtoll(s, &p, 10); #else r = strtol(s, &p, 10); @@ -591,4 +595,3 @@ { return bb_test(argc, argv); } - Modified: trunk/busybox/libbb/u_signal_names.c =================================================================== --- trunk/busybox/libbb/u_signal_names.c 2007-04-30 21:23:22 UTC (rev 18533) +++ trunk/busybox/libbb/u_signal_names.c 2007-05-01 20:07:29 UTC (rev 18534) @@ -9,20 +9,111 @@ #include "libbb.h" -static const struct signal_name { - int number; - char name[5]; -} signals[] = { +static const char signals[32][7] = { // SUSv3 says kill must support these, and specifies the numerical values, // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html // TODO: "[SIG]EXIT" shouldn't work for kill, right? - {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"}, {6, "ABRT"}, {9, "KILL"}, - {14, "ALRM"}, {15, "TERM"}, + // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"}, + // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"} // And Posix adds the following: - {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"}, - {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"}, - {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"}, - {SIGTTOU, "TTOU"} + // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"}, + // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"}, + // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"}, + // {SIGTTOU, "TTOU"} + [0] = "EXIT", +#ifdef SIGHUP + [SIGHUP ] = "HUP", +#endif +#ifdef SIGINT + [SIGINT ] = "INT", +#endif +#ifdef SIGQUIT + [SIGQUIT ] = "QUIT", +#endif +#ifdef SIGILL + [SIGILL ] = "ILL", +#endif +#ifdef SIGTRAP + [SIGTRAP ] = "TRAP", +#endif +#ifdef SIGABRT + [SIGABRT ] = "ABRT", +#endif +#ifdef SIGBUS + [SIGBUS ] = "BUS", +#endif +#ifdef SIGFPE + [SIGFPE ] = "FPE", +#endif +#ifdef SIGKILL + [SIGKILL ] = "KILL", +#endif +#ifdef SIGUSR1 + [SIGUSR1 ] = "USR1", +#endif +#ifdef SIGSEGV + [SIGSEGV ] = "SEGV", +#endif +#ifdef SIGUSR2 + [SIGUSR2 ] = "USR2", +#endif +#ifdef SIGPIPE + [SIGPIPE ] = "PIPE", +#endif +#ifdef SIGALRM + [SIGALRM ] = "ALRM", +#endif +#ifdef SIGTERM + [SIGTERM ] = "TERM", +#endif +#ifdef SIGSTKFLT + [SIGSTKFLT] = "STKFLT", +#endif +#ifdef SIGCHLD + [SIGCHLD ] = "CHLD", +#endif +#ifdef SIGCONT + [SIGCONT ] = "CONT", +#endif +#ifdef SIGSTOP + [SIGSTOP ] = "STOP", +#endif +#ifdef SIGTSTP + [SIGTSTP ] = "TSTP", +#endif +#ifdef SIGTTIN + [SIGTTIN ] = "TTIN", +#endif +#ifdef SIGTTOU + [SIGTTOU ] = "TTOU", +#endif +#ifdef SIGURG + [SIGURG ] = "URG", +#endif +#ifdef SIGXCPU + [SIGXCPU ] = "XCPU", +#endif +#ifdef SIGXFSZ + [SIGXFSZ ] = "XFSZ", +#endif +#ifdef SIGVTALRM + [SIGVTALRM] = "VTALRM", +#endif +#ifdef SIGPROF + [SIGPROF ] = "PROF", +#endif +#ifdef SIGWINCH + [SIGWINCH ] = "WINCH", +#endif +#ifdef SIGPOLL + [SIGPOLL ] = "POLL", +#endif +#ifdef SIGPWR + [SIGPWR ] = "PWR", +#endif +#ifdef SIGSYS + [SIGSYS ] = "SYS", +#endif }; // Convert signal name to number. @@ -32,12 +123,28 @@ int i; i = bb_strtou(name, NULL, 10); - if (!errno) return i; - for (i = 0; i < sizeof(signals) / sizeof(struct signal_name); i++) - if (strcasecmp(name, signals[i].name) == 0 - || (strncasecmp(name, "SIG", 3) == 0 - && strcasecmp(&name[3], signals[i].name) == 0)) - return signals[i].number; + if (!errno) + return i; + if (strncasecmp(name, "SIG", 3) == 0) + name += 3; + for (i = 0; i < sizeof(signals) / sizeof(signals[0]); i++) + if (strcasecmp(name, signals[i]) == 0) + return i; + +#if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO)) + /* These are aliased to other names */ + if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') { +#ifdef SIGIO + if (!name[2]) + return SIGIO; +#endif +#ifdef SIGIOT + if ((name[2] | 0x20) == 't' && !name[3]) + return SIGIOT; +#endif + } +#endif + return -1; } @@ -45,12 +152,9 @@ const char *get_signame(int number) { - int i; - - for (i=0; i < sizeof(signals) / sizeof(struct signal_name); i++) { - if (number == signals[i].number) { - return signals[i].name; - } + if ((unsigned)number < sizeof(signals) / sizeof(signals[0])) { + if (signals[number][0]) /* if it's not an empty str */ + return signals[number]; } return itoa(number); Modified: trunk/busybox/procps/kill.c =================================================================== --- trunk/busybox/procps/kill.c 2007-04-30 21:23:22 UTC (rev 18533) +++ trunk/busybox/procps/kill.c 2007-05-01 20:07:29 UTC (rev 18534) @@ -51,7 +51,9 @@ if (argc == 1) { /* Print the whole signal list */ for (signo = 1; signo < 32; signo++) { - puts(get_signame(signo)); + const char *name = get_signame(signo); + if (!isdigit(name[0])) + puts(name); } } else { /* -l */ while ((arg = *++argv)) { Modified: trunk/busybox/procps/ps.c =================================================================== --- trunk/busybox/procps/ps.c 2007-04-30 21:23:22 UTC (rev 18533) +++ trunk/busybox/procps/ps.c 2007-05-01 20:07:29 UTC (rev 18534) @@ -47,18 +47,21 @@ sprintf(buf, "%*u", size, ps->pgid); } -static void func_vsz(char *buf, int size, const procps_status_t *ps) +static void put_u(char *buf, int size, unsigned u) { char buf5[5]; - smart_ulltoa5( ((unsigned long long)ps->vsz) << 10, buf5); + smart_ulltoa5( ((unsigned long long)u) << 10, buf5); sprintf(buf, "%.*s", size, buf5); } +static void func_vsz(char *buf, int size, const procps_status_t *ps) +{ + put_u(buf, size, ps->vsz); +} + static void func_rss(char *buf, int size, const procps_status_t *ps) { - char buf5[5]; - smart_ulltoa5( ((unsigned long long)ps->rss) << 10, buf5); - sprintf(buf, "%.*s", size, buf5); + put_u(buf, size, ps->rss); } static void func_tty(char *buf, int size, const procps_status_t *ps) @@ -383,7 +386,7 @@ len = printf("%5u %-8s %s ", p->pid, user, p->state); else - len = printf("%5u %-8s %6ld %s ", + len = printf("%5u %-8s %6u %s ", p->pid, user, p->vsz, p->state); } From bugs at busybox.net Tue May 1 13:23:23 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Tue, 1 May 2007 13:23:23 -0700 Subject: [BusyBox 0001330]: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Message-ID: The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=1330 ====================================================================== Reported By: edh Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1330 Category: Other Reproducibility: always Severity: major Priority: normal Status: assigned ====================================================================== Date Submitted: 05-01-2007 13:23 PDT Last Modified: 05-01-2007 13:23 PDT ====================================================================== Summary: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Description: When start-stop-daemon is starting the httpd applet, and told to make a pidfile, it does so, but creates a pidfile containing the pid of the original process not the running one. httpd probably starts and forks, letting the parent die. There should be an option to httpd to prevent this so you can use pidfiles for it created by start-stop-daemon. ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 05-01-07 13:23 edh New Issue 05-01-07 13:23 edh Status new => assigned 05-01-07 13:23 edh Assigned To => BusyBox ====================================================================== From bugs at busybox.net Wed May 2 00:18:06 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 00:18:06 -0700 Subject: [BusyBox 0001331]: override udhcp Message-ID: <7bba5ddb3c04e0b4b0fec55337685b92@busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=1331 ====================================================================== Reported By: ncopa Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1331 Category: Networking Support Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 05-02-2007 00:18 PDT Last Modified: 05-02-2007 00:18 PDT ====================================================================== Summary: override udhcp Description: applies 1.5.0 (product version above needs an update btw...) If udhcpc is enabled it is not possible to use other dhcp clients. I would be nice to be able to have a dhcp client in busybox but still be able to override it, runtime, if user find udhcp not be good enough. That is how it was in 1.4.x ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 05-02-07 00:18 ncopa New Issue 05-02-07 00:18 ncopa Status new => assigned 05-02-07 00:18 ncopa Assigned To => BusyBox ====================================================================== From bugs at busybox.net Wed May 2 03:00:25 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 03:00:25 -0700 Subject: [BusyBox 0000436]: Duplicate messages suppressing Message-ID: <625609057ccbaeb803029d0c89775742@bugs.busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=436 ====================================================================== Reported By: Dmitry Bazhenov Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 436 Category: New Features Reproducibility: N/A Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 09-17-2005 03:15 PDT Last Modified: 05-02-2007 03:00 PDT ====================================================================== Summary: Duplicate messages suppressing Description: This patch add feature of suppressing duplicate messages. ====================================================================== ---------------------------------------------------------------------- vapier - 09-17-05 21:46 ---------------------------------------------------------------------- half that patch has dos newline crap, please fix what kind of filesize difference does this make ? if it's significant, should make this a build option ---------------------------------------------------------------------- vda - 09-30-06 12:45 ---------------------------------------------------------------------- What's the point in duplicating syslog misfeatures? It already does too many things: listens on /dev/log, writes to files, rotates logs, sends UDP packets... all of those should be separate small utilities btw... ---------------------------------------------------------------------- jovicv - 05-02-07 03:00 ---------------------------------------------------------------------- I am using several programs, which write same log message over and over. The message looks like this "Written 28820 bytes to socket." Because of that, syslogd uses more CPU then normal. If the duplicated messages were suppressed, all would be solved. I see this as an important feature, which I would certanly used if it was there. Issue History Date Modified Username Field Change ====================================================================== 09-17-05 03:15 Dmitry BazhenovNew Issue 09-17-05 03:15 Dmitry BazhenovStatus new => assigned 09-17-05 03:15 Dmitry BazhenovAssigned To => BusyBox 09-17-05 03:15 Dmitry BazhenovFile Added: syslogd.c-suppress_duplicates.patch 09-17-05 21:46 vapier Note Added: 0000546 09-30-06 12:45 vda Note Added: 0001667 05-02-07 03:00 jovicv Note Added: 0002335 ====================================================================== From vda at busybox.net Wed May 2 08:34:50 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 08:34:50 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070502153450.92EF5485C1@busybox.net> Author: vda Date: 2007-05-02 08:34:47 -0700 (Wed, 02 May 2007) New Revision: 18538 Log: hush: fix incorrect exitcodes without job control Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-02 08:10:22 UTC (rev 18537) +++ trunk/busybox/shell/hush.c 2007-05-02 15:34:47 UTC (rev 18538) @@ -110,8 +110,8 @@ * output pretty */ static const struct { int mode; - int default_fd; - const char *descrip; + signed char default_fd; + char descrip[3]; } redir_table[] = { { 0, 0, "()" }, { O_RDONLY, 0, "<" }, @@ -255,7 +255,8 @@ static const char *PS2; #endif -static struct variables shell_ver = { NULL, "HUSH_VERSION", "0.01", 1, 1 }; +#define HUSH_VER_STR "0.02" +static struct variables shell_ver = { NULL, "HUSH_VERSION", HUSH_VER_STR, 1, 1 }; static struct variables *top_vars = &shell_ver; #define B_CHUNK 100 @@ -296,12 +297,6 @@ int (*function) (char **argv); /* function ptr */ }; -/* belongs in busybox.h */ -static int max(int a, int b) -{ - return (a > b) ? a : b; -} - #ifdef DEBUG_SHELL #define debug_printf(...) fprintf(stderr, __VA_ARGS__) /* broken, of course, but OK for testing */ @@ -590,14 +585,14 @@ sigexit(- (exitcode & 0xff)); } -#else /* !INTERACTIVE */ +#else /* !JOB */ #define set_fatal_sighandler(handler) ((void)0) #define set_jobctrl_sighandler(handler) ((void)0) #define set_misc_sighandler(handler) ((void)0) -#define hush_exit(e) exit(-(e)) +#define hush_exit(e) exit(e) -#endif /* INTERACTIVE */ +#endif /* JOB */ static const char *set_cwd(void) @@ -957,7 +952,7 @@ if (o->length + len > o->maxlen) { char *old_data = o->data; /* assert(data == NULL || o->maxlen != 0); */ - o->maxlen += max(2*len, B_CHUNK); + o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK); o->data = realloc(o->data, 1 + o->maxlen); if (o->data == NULL) { free(old_data); @@ -3299,7 +3294,7 @@ hush_exit(xfunc_error_retval); } #if !ENABLE_FEATURE_SH_EXTRA_QUIET - printf("\n\n%s hush - the humble shell v0.02\n", BB_BANNER); + printf("\n\n%s hush - the humble shell v"HUSH_VER_STR"\n", BB_BANNER); printf("Enter 'help' for a list of built-in commands.\n\n"); #endif } From vda at busybox.net Wed May 2 08:35:45 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 08:35:45 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070502153545.94711485C5@busybox.net> Author: vda Date: 2007-05-02 08:35:45 -0700 (Wed, 02 May 2007) New Revision: 18539 Log: hush: add debugging for tracing execution, add FIXME for 'true | exit 3; echo $?' case Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-02 15:34:47 UTC (rev 18538) +++ trunk/busybox/shell/hush.c 2007-05-02 15:35:45 UTC (rev 18539) @@ -85,6 +85,7 @@ //#define DEBUG_SHELL /* Finer-grained debug switch */ //#define DEBUG_SHELL_JOBS +//#define DEBUG_SHELL_EXECUTION #if !ENABLE_HUSH_INTERACTIVE #undef ENABLE_FEATURE_EDITING @@ -315,6 +316,12 @@ #define debug_jobs_printf(...) do {} while (0) #endif +#ifdef DEBUG_SHELL_EXECUTION +#define debug_exec_printf(...) fprintf(stderr, __VA_ARGS__) +#else +#define debug_exec_printf(...) do {} while (0) +#endif + #define final_printf debug_printf static void __syntax(int line) @@ -1322,11 +1329,11 @@ } if (child->group) { - debug_printf("runtime nesting to group\n"); // FIXME: do not modify globals! Think vfork! #if ENABLE_HUSH_INTERACTIVE interactive_fd = 0; /* crucial!!!! */ #endif + debug_exec_printf("pseudo_exec: run_list_real\n"); rcode = run_list_real(child->group); /* OK to leak memory by not calling free_pipe_list, * since this process is about to exit */ @@ -1641,6 +1648,8 @@ int rcode; const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG); + debug_exec_printf("run_pipe_real start:\n"); + nextin = 0; #if ENABLE_HUSH_JOB pi->pgrp = -1; @@ -1658,8 +1667,10 @@ setup_redirects(child, squirrel); /* XXX could we merge code with following builtin case, * by creating a pseudo builtin that calls run_list_real? */ + debug_exec_printf(": run_list_real\n"); rcode = run_list_real(child->group); restore_redirects(squirrel); + debug_exec_printf("run_pipe_real return %d\n", rcode); return rcode; } @@ -1707,8 +1718,10 @@ char *str; str = make_string(argv + i); + debug_exec_printf(": parse_string_outer '%s'\n", str); parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); free(str); + debug_exec_printf("run_pipe_real return %d\n", last_return_code); return last_return_code; } for (x = bltins; x->cmd; x++) { @@ -1725,8 +1738,10 @@ * things seem to work with glibc. */ // TODO: fflush(NULL)? setup_redirects(child, squirrel); + debug_exec_printf(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]); rcode = x->function(argv + i); restore_redirects(squirrel); + debug_exec_printf("run_pipe_real return %d\n", rcode); return rcode; } } @@ -1735,8 +1750,10 @@ const struct bb_applet *a = find_applet_by_name(argv[i]); if (a && a->nofork) { setup_redirects(child, squirrel); + debug_exec_printf(": run_single_fg_nofork '%s' '%s'...\n", argv[i], argv[i+1]); rcode = run_single_fg_nofork(pi, a, argv + i); restore_redirects(squirrel); + debug_exec_printf("run_pipe_real return %d\n", rcode); return rcode; } } @@ -1751,6 +1768,7 @@ for (i = 0; i < pi->num_progs; i++) { child = &(pi->progs[i]); + debug_exec_printf(": pipe member '%s' '%s'...\n", child->argv[0], child->argv[1]); /* pipes are inserted between pairs of commands */ if ((i + 1) < pi->num_progs) { @@ -1831,6 +1849,7 @@ but it doesn't matter */ nextin = pipefds[0]; } + debug_exec_printf("run_pipe_real return -1\n"); return -1; } @@ -1846,18 +1865,23 @@ int flag_restore = 0; int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; + + debug_exec_printf("run_list_real start:\n"); + /* check syntax for "for" */ for (rpipe = pi; rpipe; rpipe = rpipe->next) { if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR) && (rpipe->next == NULL) ) { syntax(); + debug_exec_printf("run_list_real return 1\n"); return 1; } if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL) || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN) ) { syntax(); + debug_exec_printf("run_list_real return 1\n"); return 1; } } @@ -1933,8 +1957,8 @@ if (pi->num_progs == 0) continue; save_num_progs = pi->num_progs; /* save number of programs */ + debug_exec_printf(": run_pipe_real with %d members\n", pi->num_progs); rcode = run_pipe_real(pi); - debug_printf("run_pipe_real returned %d\n", rcode); if (rcode != -1) { /* We only ran a builtin: rcode was set by the return value * of run_pipe_real(), and we don't need to wait for anything. */ @@ -1972,6 +1996,7 @@ } checkjobs(NULL); } + debug_exec_printf("run_list_real return %d\n", rcode); return rcode; } @@ -2047,6 +2072,7 @@ { int rcode = 0; if (fake_mode == 0) { + debug_exec_printf("run_list: run_list_real with %d members\n", pi->num_progs); rcode = run_list_real(pi); } /* free_pipe_list has the side effect of clearing memory @@ -3083,6 +3109,10 @@ * from builtin_source() */ static int parse_stream_outer(struct in_str *inp, int flag) { +// FIXME: 'true | exit 3; echo $?' is parsed as a whole, +// as a result $? is replaced by 0, not 3! +// Need to stop & execute stuff at ';', not parse till EOL! + struct p_context ctx; o_string temp = NULL_O_STRING; int rcode; @@ -3102,6 +3132,7 @@ if (rcode != 1 && ctx.old_flag == 0) { done_word(&temp, &ctx); done_pipe(&ctx, PIPE_SEQ); + debug_exec_printf("parse_stream_outer: run_list\n"); run_list(ctx.list_head); } else { if (ctx.old_flag != 0) { From bugs at busybox.net Wed May 2 10:57:44 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 10:57:44 -0700 Subject: [BusyBox 0001329]: Patch for "util-linux/mdev.c": make it able to create symlinks and subdirectories Message-ID: <8681d9dfdc725ccbcc21fe3bf42b7eb3@busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=1329 ====================================================================== Reported By: Souf Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1329 Category: New Features Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 04-29-2007 10:44 PDT Last Modified: 05-02-2007 10:57 PDT ====================================================================== Summary: Patch for "util-linux/mdev.c": make it able to create symlinks and subdirectories Description: This patch adds to mdev.c the ability to create symlinks and subdirectories: examples: stderr -> /proc/self/fd/2 pcmC[0-9]D[0-9]c 0:0 0666 >> /dev/snd/ 0755 modified files: util-linux/mdev.c util-linux/Config.in docs/mdev.txt The patch corrects also the bug 0001299 I wish that this patch be deeply tested before a possible integration ====================================================================== ---------------------------------------------------------------------- vapier - 05-02-07 10:57 ---------------------------------------------------------------------- you removed support for program execution which is not desirable i'll post a diff patch to the busybox mailing list we've been using in Blackfin/uClinux-dist Issue History Date Modified Username Field Change ====================================================================== 04-29-07 10:44 Souf New Issue 04-29-07 10:44 Souf Status new => assigned 04-29-07 10:44 Souf Assigned To => BusyBox 04-29-07 10:44 Souf File Added: mdev.patch 05-02-07 10:57 vapier Note Added: 0002336 ====================================================================== From bugs at busybox.net Wed May 2 13:53:24 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 13:53:24 -0700 Subject: [BusyBox 0001330]: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Message-ID: A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=1330 ====================================================================== Reported By: edh Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1330 Category: Other Reproducibility: always Severity: major Priority: normal Status: assigned ====================================================================== Date Submitted: 05-01-2007 13:23 PDT Last Modified: 05-02-2007 13:53 PDT ====================================================================== Summary: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Description: When start-stop-daemon is starting the httpd applet, and told to make a pidfile, it does so, but creates a pidfile containing the pid of the original process not the running one. httpd probably starts and forks, letting the parent die. There should be an option to httpd to prevent this so you can use pidfiles for it created by start-stop-daemon. ====================================================================== ---------------------------------------------------------------------- edh - 05-02-07 13:53 ---------------------------------------------------------------------- This is also the case when using start-stop-daemon to start telnetd. So I guess it applies to all servers that fork immediately and detach. I needed the pid for httpd, and now need it for telnetd. There is a work around in some cases. You can use start-stop-daemon to send signals, like SIGHUP to servers, removing the need for pidfiles generally. Issue History Date Modified Username Field Change ====================================================================== 05-01-07 13:23 edh New Issue 05-01-07 13:23 edh Status new => assigned 05-01-07 13:23 edh Assigned To => BusyBox 05-01-07 13:23 edh Issue Monitored: edh 05-02-07 13:53 edh Note Added: 0002337 ====================================================================== From vda at busybox.net Wed May 2 14:38:45 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 14:38:45 -0700 (PDT) Subject: svn commit: trunk/busybox/networking Message-ID: <20070502213845.67594485D1@busybox.net> Author: vda Date: 2007-05-02 14:38:44 -0700 (Wed, 02 May 2007) New Revision: 18541 Log: ifupdown: reread state file before rewriting it. Fixes "ifup started another ifup" state corruption bug. Patch by Natanael Copa . Modified: trunk/busybox/networking/ifupdown.c Changeset: Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2007-05-02 18:20:58 UTC (rev 18540) +++ trunk/busybox/networking/ifupdown.c 2007-05-02 21:38:44 UTC (rev 18541) @@ -1083,15 +1083,33 @@ return NULL; } +/* read the previous state from the state file */ +static llist_t *read_iface_state(void) +{ + llist_t *state_list = NULL; + FILE *state_fp = fopen("/var/run/ifstate", "r"); + + if (state_fp) { + char *start, *end_ptr; + while ((start = xmalloc_fgets(state_fp)) != NULL) { + /* We should only need to check for a single character */ + end_ptr = start + strcspn(start, " \t\n"); + *end_ptr = '\0'; + llist_add_to(&state_list, start); + } + fclose(state_fp); + } + return state_list; +} + + int ifupdown_main(int argc, char **argv); int ifupdown_main(int argc, char **argv) { int (*cmds)(struct interface_defn_t *) = NULL; struct interfaces_file_t *defn; - llist_t *state_list = NULL; llist_t *target_list = NULL; const char *interfaces = "/etc/network/interfaces"; - FILE *state_fp; bool any_failures = 0; cmds = iface_down; @@ -1118,32 +1136,9 @@ startup_PATH = getenv("PATH"); if (!startup_PATH) startup_PATH = ""; - /* Read the previous state from the state file */ - state_fp = fopen("/var/run/ifstate", "r"); - if (state_fp) { - char *start, *end_ptr; - while ((start = xmalloc_fgets(state_fp)) != NULL) { - /* We should only need to check for a single character */ - end_ptr = start + strcspn(start, " \t\n"); - *end_ptr = '\0'; - llist_add_to(&state_list, start); - } - fclose(state_fp); - } - /* Create a list of interfaces to work on */ if (DO_ALL) { - if (cmds == iface_up) { - target_list = defn->autointerfaces; - } else { - /* iface_down */ - const llist_t *list = state_list; - while (list) { - llist_add_to_end(&target_list, xstrdup(list->data)); - list = list->link; - } - target_list = defn->autointerfaces; - } + target_list = defn->autointerfaces; } else { llist_add_to_end(&target_list, argv[optind]); } @@ -1170,6 +1165,7 @@ } if (!FORCE) { + llist_t *state_list = read_iface_state(); const llist_t *iface_state = find_iface_state(state_list, iface); if (cmds == iface_up) { @@ -1185,6 +1181,7 @@ continue; } } + llist_free(state_list, free); } #if ENABLE_FEATURE_IFUPDOWN_MAPPING @@ -1239,6 +1236,8 @@ bb_error_msg("ignoring unknown interface %s", liface); any_failures = 1; } else { + /* update the state file */ + llist_t *state_list = read_iface_state(); llist_t *iface_state = find_iface_state(state_list, iface); if (cmds == iface_up) { @@ -1254,19 +1253,21 @@ llist_unlink(&state_list, iface_state); free(llist_pop(&iface_state)); } - } - } - /* Actually write the new state */ - if (!NO_ACT) { - state_fp = xfopen("/var/run/ifstate", "w"); - while (state_list) { - if (state_list->data) { - fprintf(state_fp, "%s\n", state_list->data); + /* Actually write the new state */ + if (!NO_ACT) { + FILE *state_fp = xfopen("/var/run/ifstate", "w"); + llist_t *state = state_list; + while (state) { + if (state->data) { + fprintf(state_fp, "%s\n", state->data); + } + state = state->link; + } + fclose(state_fp); } - state_list = state_list->link; + llist_free(state_list, free); } - fclose(state_fp); } return any_failures; From vda at busybox.net Wed May 2 14:39:30 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 14:39:30 -0700 (PDT) Subject: svn commit: trunk/busybox/sysklogd Message-ID: <20070502213930.3B7EC485DE@busybox.net> Author: vda Date: 2007-05-02 14:39:29 -0700 (Wed, 02 May 2007) New Revision: 18542 Log: klogd: remove dependency on syslogd Modified: trunk/busybox/sysklogd/Config.in Changeset: Modified: trunk/busybox/sysklogd/Config.in =================================================================== --- trunk/busybox/sysklogd/Config.in 2007-05-02 21:38:44 UTC (rev 18541) +++ trunk/busybox/sysklogd/Config.in 2007-05-02 21:39:29 UTC (rev 18542) @@ -88,8 +88,6 @@ config KLOGD bool "klogd" default n - depends on SYSLOGD - select FEATURE_SYSLOG help klogd is a utility which intercepts and logs all messages from the Linux kernel and sends the messages From vda at busybox.net Wed May 2 14:40:23 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 14:40:23 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070502214023.C0CAF485DD@busybox.net> Author: vda Date: 2007-05-02 14:40:23 -0700 (Wed, 02 May 2007) New Revision: 18543 Log: hush: simplify debugging prints a little bit Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-02 21:39:29 UTC (rev 18542) +++ trunk/busybox/shell/hush.c 2007-05-02 21:40:23 UTC (rev 18543) @@ -80,13 +80,38 @@ #include "busybox.h" #include /* glob, of course */ #include /* should be pretty obvious */ - /* #include */ -//#define DEBUG_SHELL + + +/* If you comment out one of these below, it will be #defined later + * to perform debug printfs to stderr: */ +#define debug_printf(...) do {} while (0) /* Finer-grained debug switch */ -//#define DEBUG_SHELL_JOBS -//#define DEBUG_SHELL_EXECUTION +#define debug_printf_jobs(...) do {} while (0) +#define debug_printf_exec(...) do {} while (0) + +#ifndef debug_printf +#define debug_printf(...) fprintf(stderr, __VA_ARGS__) +/* broken, of course, but OK for testing */ +static const char *indenter(int i) +{ + static const char blanks[] = " "; + return &blanks[sizeof(blanks) - i - 1]; +} +#endif +#define final_printf debug_printf + +#ifndef debug_printf_jobs +#define debug_printf_jobs(...) fprintf(stderr, __VA_ARGS__) +#define DEBUG_SHELL_JOBS 1 +#endif + +#ifndef debug_printf_exec +#define debug_printf_exec(...) fprintf(stderr, __VA_ARGS__) +#endif + + #if !ENABLE_HUSH_INTERACTIVE #undef ENABLE_FEATURE_EDITING #define ENABLE_FEATURE_EDITING 0 @@ -298,32 +323,6 @@ int (*function) (char **argv); /* function ptr */ }; -#ifdef DEBUG_SHELL -#define debug_printf(...) fprintf(stderr, __VA_ARGS__) -/* broken, of course, but OK for testing */ -static char *indenter(int i) -{ - static char blanks[] = " "; - return &blanks[sizeof(blanks) - i - 1]; -} -#else -#define debug_printf(...) do {} while (0) -#endif - -#ifdef DEBUG_SHELL_JOBS -#define debug_jobs_printf(...) fprintf(stderr, __VA_ARGS__) -#else -#define debug_jobs_printf(...) do {} while (0) -#endif - -#ifdef DEBUG_SHELL_EXECUTION -#define debug_exec_printf(...) fprintf(stderr, __VA_ARGS__) -#else -#define debug_exec_printf(...) do {} while (0) -#endif - -#define final_printf debug_printf - static void __syntax(int line) { bb_error_msg("syntax error hush.c:%d", line); @@ -514,7 +513,7 @@ static void handler_ctrl_c(int sig) { - debug_jobs_printf("got sig %d\n", sig); + debug_printf_jobs("got sig %d\n", sig); // as usual we can have all kinds of nasty problems with leaked malloc data here siglongjmp(nofork_jb, 1); } @@ -523,20 +522,20 @@ { pid_t pid; - debug_jobs_printf("got tty sig %d\n", sig); + debug_printf_jobs("got tty sig %d\n", sig); pid = fork(); if (pid < 0) /* can't fork. Pretend there were no Ctrl-Z */ return; - debug_jobs_printf("bg'ing nofork\n"); + debug_printf_jobs("bg'ing nofork\n"); nofork_save.saved = 0; /* flag the fact that Ctrl-Z was handled */ nofork_pipe->running_progs = 1; nofork_pipe->stopped_progs = 0; if (!pid) { /* child */ - debug_jobs_printf("setting pgrp for child\n"); + debug_printf_jobs("setting pgrp for child\n"); setpgrp(); set_every_sighandler(SIG_DFL); raise(SIGTSTP); /* resend TSTP so that child will be stopped */ - debug_jobs_printf("returning to child\n"); + debug_printf_jobs("returning to child\n"); /* return to nofork, it will eventually exit now, * not return back to shell */ return; @@ -766,9 +765,9 @@ } /* Restart the processes in the job */ - debug_jobs_printf("reviving %d procs, pgrp %d\n", pi->num_progs, pi->pgrp); + debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_progs, pi->pgrp); for (i = 0; i < pi->num_progs; i++) { - debug_jobs_printf("reviving pid %d\n", pi->progs[i].pid); + debug_printf_jobs("reviving pid %d\n", pi->progs[i].pid); pi->progs[i].is_stopped = 0; } pi->stopped_progs = 0; @@ -1333,7 +1332,7 @@ #if ENABLE_HUSH_INTERACTIVE interactive_fd = 0; /* crucial!!!! */ #endif - debug_exec_printf("pseudo_exec: run_list_real\n"); + debug_printf_exec("pseudo_exec: run_list_real\n"); rcode = run_list_real(child->group); /* OK to leak memory by not calling free_pipe_list, * since this process is about to exit */ @@ -1478,20 +1477,20 @@ #ifdef DEBUG_SHELL_JOBS if (WIFSTOPPED(status)) - debug_jobs_printf("pid %d stopped by sig %d (exitcode %d)\n", + debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n", childpid, WSTOPSIG(status), WEXITSTATUS(status)); if (WIFSIGNALED(status)) - debug_jobs_printf("pid %d killed by sig %d (exitcode %d)\n", + debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n", childpid, WTERMSIG(status), WEXITSTATUS(status)); if (WIFEXITED(status)) - debug_jobs_printf("pid %d exited, exitcode %d\n", + debug_printf_jobs("pid %d exited, exitcode %d\n", childpid, WEXITSTATUS(status)); #endif /* Were we asked to wait for fg pipe? */ if (fg_pipe) { int i; for (i = 0; i < fg_pipe->num_progs; i++) { - debug_jobs_printf("check pid %d\n", fg_pipe->progs[i].pid); + debug_printf_jobs("check pid %d\n", fg_pipe->progs[i].pid); if (fg_pipe->progs[i].pid == childpid) { /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */ if (dead) { @@ -1504,7 +1503,7 @@ fg_pipe->progs[i].is_stopped = 1; fg_pipe->stopped_progs++; } - debug_jobs_printf("fg_pipe: running_progs %d stopped_progs %d\n", + debug_printf_jobs("fg_pipe: running_progs %d stopped_progs %d\n", fg_pipe->running_progs, fg_pipe->stopped_progs); if (fg_pipe->running_progs - fg_pipe->stopped_progs <= 0) { /* All processes in fg pipe have exited/stopped */ @@ -1606,7 +1605,7 @@ * Sighandler has longjmped us here */ signal(SIGINT, SIG_IGN); signal(SIGTSTP, SIG_IGN); - debug_jobs_printf("Exiting nofork early\n"); + debug_printf_jobs("Exiting nofork early\n"); restore_nofork_data(&nofork_save); if (nofork_save.saved == 0) /* Ctrl-Z, not Ctrl-C */ insert_bg_job(pi); @@ -1648,7 +1647,7 @@ int rcode; const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG); - debug_exec_printf("run_pipe_real start:\n"); + debug_printf_exec("run_pipe_real start:\n"); nextin = 0; #if ENABLE_HUSH_JOB @@ -1667,10 +1666,10 @@ setup_redirects(child, squirrel); /* XXX could we merge code with following builtin case, * by creating a pseudo builtin that calls run_list_real? */ - debug_exec_printf(": run_list_real\n"); + debug_printf_exec(": run_list_real\n"); rcode = run_list_real(child->group); restore_redirects(squirrel); - debug_exec_printf("run_pipe_real return %d\n", rcode); + debug_printf_exec("run_pipe_real return %d\n", rcode); return rcode; } @@ -1718,10 +1717,10 @@ char *str; str = make_string(argv + i); - debug_exec_printf(": parse_string_outer '%s'\n", str); + debug_printf_exec(": parse_string_outer '%s'\n", str); parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); free(str); - debug_exec_printf("run_pipe_real return %d\n", last_return_code); + debug_printf_exec("run_pipe_real return %d\n", last_return_code); return last_return_code; } for (x = bltins; x->cmd; x++) { @@ -1738,10 +1737,10 @@ * things seem to work with glibc. */ // TODO: fflush(NULL)? setup_redirects(child, squirrel); - debug_exec_printf(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]); + debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]); rcode = x->function(argv + i); restore_redirects(squirrel); - debug_exec_printf("run_pipe_real return %d\n", rcode); + debug_printf_exec("run_pipe_real return %d\n", rcode); return rcode; } } @@ -1750,10 +1749,10 @@ const struct bb_applet *a = find_applet_by_name(argv[i]); if (a && a->nofork) { setup_redirects(child, squirrel); - debug_exec_printf(": run_single_fg_nofork '%s' '%s'...\n", argv[i], argv[i+1]); + debug_printf_exec(": run_single_fg_nofork '%s' '%s'...\n", argv[i], argv[i+1]); rcode = run_single_fg_nofork(pi, a, argv + i); restore_redirects(squirrel); - debug_exec_printf("run_pipe_real return %d\n", rcode); + debug_printf_exec("run_pipe_real return %d\n", rcode); return rcode; } } @@ -1768,7 +1767,7 @@ for (i = 0; i < pi->num_progs; i++) { child = &(pi->progs[i]); - debug_exec_printf(": pipe member '%s' '%s'...\n", child->argv[0], child->argv[1]); + debug_printf_exec(": pipe member '%s' '%s'...\n", child->argv[0], child->argv[1]); /* pipes are inserted between pairs of commands */ if ((i + 1) < pi->num_progs) { @@ -1849,7 +1848,7 @@ but it doesn't matter */ nextin = pipefds[0]; } - debug_exec_printf("run_pipe_real return -1\n"); + debug_printf_exec("run_pipe_real return -1\n"); return -1; } @@ -1866,7 +1865,7 @@ int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; - debug_exec_printf("run_list_real start:\n"); + debug_printf_exec("run_list_real start:\n"); /* check syntax for "for" */ for (rpipe = pi; rpipe; rpipe = rpipe->next) { @@ -1874,14 +1873,14 @@ && (rpipe->next == NULL) ) { syntax(); - debug_exec_printf("run_list_real return 1\n"); + debug_printf_exec("run_list_real return 1\n"); return 1; } if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL) || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN) ) { syntax(); - debug_exec_printf("run_list_real return 1\n"); + debug_printf_exec("run_list_real return 1\n"); return 1; } } @@ -1957,7 +1956,7 @@ if (pi->num_progs == 0) continue; save_num_progs = pi->num_progs; /* save number of programs */ - debug_exec_printf(": run_pipe_real with %d members\n", pi->num_progs); + debug_printf_exec(": run_pipe_real with %d members\n", pi->num_progs); rcode = run_pipe_real(pi); if (rcode != -1) { /* We only ran a builtin: rcode was set by the return value @@ -1996,7 +1995,7 @@ } checkjobs(NULL); } - debug_exec_printf("run_list_real return %d\n", rcode); + debug_printf_exec("run_list_real return %d\n", rcode); return rcode; } @@ -2072,7 +2071,7 @@ { int rcode = 0; if (fake_mode == 0) { - debug_exec_printf("run_list: run_list_real with %d members\n", pi->num_progs); + debug_printf_exec("run_list: run_list_real with %d members\n", pi->num_progs); rcode = run_list_real(pi); } /* free_pipe_list has the side effect of clearing memory @@ -3132,7 +3131,7 @@ if (rcode != 1 && ctx.old_flag == 0) { done_word(&temp, &ctx); done_pipe(&ctx, PIPE_SEQ); - debug_exec_printf("parse_stream_outer: run_list\n"); + debug_printf_exec("parse_stream_outer: run_list\n"); run_list(ctx.list_head); } else { if (ctx.old_flag != 0) { From bugs at busybox.net Wed May 2 15:02:26 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 15:02:26 -0700 Subject: [BusyBox 0001330]: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Message-ID: A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=1330 ====================================================================== Reported By: edh Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1330 Category: Other Reproducibility: always Severity: major Priority: normal Status: assigned ====================================================================== Date Submitted: 05-01-2007 13:23 PDT Last Modified: 05-02-2007 15:02 PDT ====================================================================== Summary: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Description: When start-stop-daemon is starting the httpd applet, and told to make a pidfile, it does so, but creates a pidfile containing the pid of the original process not the running one. httpd probably starts and forks, letting the parent die. There should be an option to httpd to prevent this so you can use pidfiles for it created by start-stop-daemon. ====================================================================== ---------------------------------------------------------------------- edh - 05-02-07 13:53 ---------------------------------------------------------------------- This is also the case when using start-stop-daemon to start telnetd. So I guess it applies to all servers that fork immediately and detach. I needed the pid for httpd, and now need it for telnetd. There is a work around in some cases. You can use start-stop-daemon to send signals, like SIGHUP to servers, removing the need for pidfiles generally. ---------------------------------------------------------------------- vda - 05-02-07 15:02 ---------------------------------------------------------------------- Auto-daemonizing programs fork children, then parent dies. ssd have no way detecting this. Most of daemons have an option to suppress daemonization: # telnetd --help -F Stay in foreground -i Run as inetd subservice # httpd --help -f Do not daemonize Use this if you start them from ssd. Issue History Date Modified Username Field Change ====================================================================== 05-01-07 13:23 edh New Issue 05-01-07 13:23 edh Status new => assigned 05-01-07 13:23 edh Assigned To => BusyBox 05-01-07 13:23 edh Issue Monitored: edh 05-02-07 13:53 edh Note Added: 0002337 05-02-07 15:02 vda Note Added: 0002338 ====================================================================== From bugs at busybox.net Wed May 2 15:02:39 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 15:02:39 -0700 Subject: [BusyBox 0001330]: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Message-ID: <002e1c5c932dbf3d8696e4cfe59dd155@busybox.net> The following issue has been CLOSED ====================================================================== http://busybox.net/bugs/view.php?id=1330 ====================================================================== Reported By: edh Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1330 Category: Other Reproducibility: always Severity: major Priority: normal Status: closed Resolution: open Fixed in Version: ====================================================================== Date Submitted: 05-01-2007 13:23 PDT Last Modified: 05-02-2007 15:02 PDT ====================================================================== Summary: start-stop-daemon with --make-pidfile and --pidfile on httpd applet creates the wrong pid# in pidfile Description: When start-stop-daemon is starting the httpd applet, and told to make a pidfile, it does so, but creates a pidfile containing the pid of the original process not the running one. httpd probably starts and forks, letting the parent die. There should be an option to httpd to prevent this so you can use pidfiles for it created by start-stop-daemon. ====================================================================== ---------------------------------------------------------------------- edh - 05-02-07 13:53 ---------------------------------------------------------------------- This is also the case when using start-stop-daemon to start telnetd. So I guess it applies to all servers that fork immediately and detach. I needed the pid for httpd, and now need it for telnetd. There is a work around in some cases. You can use start-stop-daemon to send signals, like SIGHUP to servers, removing the need for pidfiles generally. ---------------------------------------------------------------------- vda - 05-02-07 15:02 ---------------------------------------------------------------------- Auto-daemonizing programs fork children, then parent dies. ssd have no way detecting this. Most of daemons have an option to suppress daemonization: # telnetd --help -F Stay in foreground -i Run as inetd subservice # httpd --help -f Do not daemonize Use this if you start them from ssd. Issue History Date Modified Username Field Change ====================================================================== 05-01-07 13:23 edh New Issue 05-01-07 13:23 edh Status new => assigned 05-01-07 13:23 edh Assigned To => BusyBox 05-01-07 13:23 edh Issue Monitored: edh 05-02-07 13:53 edh Note Added: 0002337 05-02-07 15:02 vda Note Added: 0002338 05-02-07 15:02 vda Status assigned => closed ====================================================================== From vda at busybox.net Wed May 2 15:04:38 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 15:04:38 -0700 (PDT) Subject: svn commit: trunk/busybox/networking Message-ID: <20070502220438.B8981485DC@busybox.net> Author: vda Date: 2007-05-02 15:04:38 -0700 (Wed, 02 May 2007) New Revision: 18544 Log: ifupdown: mke it possible to use DHCP clients different from udhcp. Modified: trunk/busybox/networking/Config.in trunk/busybox/networking/ifupdown.c Changeset: Modified: trunk/busybox/networking/Config.in =================================================================== --- trunk/busybox/networking/Config.in 2007-05-02 21:40:23 UTC (rev 18543) +++ trunk/busybox/networking/Config.in 2007-05-02 22:04:38 UTC (rev 18544) @@ -266,7 +266,7 @@ default y depends on IFUPDOWN help - If you want busybox to talk IPv4, leave this on. + If you want ifup/ifdown to talk IPv4, leave this on. config FEATURE_IFUPDOWN_IPV6 bool "Enable support for IPv6" @@ -275,13 +275,14 @@ help If you need support for IPv6, turn this option on. -config FEATURE_IFUPDOWN_IPX - bool "Enable support for IPX" - default n - depends on IFUPDOWN - help - If this option is selected you can use busybox to work with IPX - networks. +### UNUSED +### config FEATURE_IFUPDOWN_IPX +### bool "Enable support for IPX" +### default n +### depends on IFUPDOWN +### help +### If this option is selected you can use busybox to work with IPX +### networks. config FEATURE_IFUPDOWN_MAPPING bool "Enable mapping support" @@ -291,6 +292,16 @@ This enables support for the "mapping" stanza, unless you have a weird network setup you don't need it. +config FEATURE_IFUPDOWN_EXTERNAL_DHCP + bool "Enable support for external dhcp clients" + default n + depends on IFUPDOWN + help + This enables support for the external dhcp clients. Clients are + tried in the following order: dhcpcd, dhclient, pump and udhcpc. + Otherwise, if udhcpc applet is enabled, it is used. + Otherwise, ifup/ifdown will have no support for DHCP. + config INETD bool "inetd" default n Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2007-05-02 21:40:23 UTC (rev 18543) +++ trunk/busybox/networking/ifupdown.c 2007-05-02 22:04:38 UTC (rev 18544) @@ -439,7 +439,7 @@ return ((result == 2) ? 2 : 0); } -#if !ENABLE_APP_UDHCPC +#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP struct dhcp_client_t { const char *name; @@ -448,32 +448,28 @@ }; static const struct dhcp_client_t ext_dhcp_clients[] = { - { "udhcpc", - "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", - "kill -TERM `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", + { "dhcpcd", + "dhcpcd[[ -h %hostname%]][[ -i %vendor%]][[ -I %clientid%]][[ -l %leasetime%]] %iface%", + "dhcpcd -k %iface%", }, + { "dhclient", + "dhclient -pf /var/run/dhclient.%iface%.pid %iface%", + "kill -9 `cat /var/run/dhclient.%iface%.pid` 2>/dev/null", + }, { "pump", "pump -i %iface%[[ -h %hostname%]][[ -l %leasehours%]]", "pump -i %iface% -k", }, - { "dhclient", - "dhclient -pf /var/run/dhclient.%iface%.pid %iface%", - "kill -9 `cat /var/run/dhclient.%iface%.pid` 2>/dev/null", + { "udhcpc", + "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", + "kill -TERM `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", }, - { "dhcpcd", - "dhcpcd[[ -h %hostname%]][[ -i %vendor%]][[ -I %clientid%]][[ -l %leasetime%]] %iface%", - "dhcpcd -k %iface%", - }, }; -#endif +#endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */ static int dhcp_up(struct interface_defn_t *ifd, execfn *exec) { -#if ENABLE_APP_UDHCPC - return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid " - "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", - ifd, exec); -#else +#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP int i, nclients = sizeof(ext_dhcp_clients) / sizeof(ext_dhcp_clients[0]); for (i = 0; i < nclients; i++) { if (exists_execable(ext_dhcp_clients[i].name)) @@ -481,15 +477,18 @@ } bb_error_msg("no dhcp clients found"); return 0; -#endif +#elif ENABLE_APP_UDHCPC + return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid " + "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", + ifd, exec); +#else + return 0; /* no dhcp support */ +#endif } static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) { -#if ENABLE_APP_UDHCPC - return execute("kill -TERM " - "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec); -#else +#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP int i, nclients = sizeof(ext_dhcp_clients) / sizeof(ext_dhcp_clients[0]); for (i = 0; i < nclients; i++) { if (exists_execable(ext_dhcp_clients[i].name)) @@ -497,6 +496,11 @@ } bb_error_msg("no dhcp clients found, using static interface shutdown"); return static_down(ifd, exec); +#elif ENABLE_APP_UDHCPC + return execute("kill -TERM " + "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec); +#else + return 0; /* no support for dhcp */ #endif } @@ -546,7 +550,7 @@ static const struct address_family_t addr_inet = { "inet", - sizeof(methods) / sizeof(struct method_t), + sizeof(methods) / sizeof(methods[0]), methods }; @@ -1074,8 +1078,8 @@ llist_t *search = state_list; while (search) { - if ((strncmp(search->data, iface, iface_len) == 0) && - (search->data[iface_len] == '=')) { + if ((strncmp(search->data, iface, iface_len) == 0) + && (search->data[iface_len] == '=')) { return search; } search = search->link; From vapier at busybox.net Wed May 2 15:07:03 2007 From: vapier at busybox.net (vapier at busybox.net) Date: Wed, 2 May 2007 15:07:03 -0700 (PDT) Subject: svn commit: trunk/busybox Message-ID: <20070502220703.CEC09485E2@busybox.net> Author: vapier Date: 2007-05-02 15:07:03 -0700 (Wed, 02 May 2007) New Revision: 18545 Log: allow people to stick custom things into Makefile.local so they dont need to update busybox files while integrating into other build systems (like uClinux-dist) Modified: trunk/busybox/Makefile.custom Changeset: Modified: trunk/busybox/Makefile.custom =================================================================== --- trunk/busybox/Makefile.custom 2007-05-02 22:04:38 UTC (rev 18544) +++ trunk/busybox/Makefile.custom 2007-05-02 22:07:03 UTC (rev 18545) @@ -143,3 +143,5 @@ .PHONY: html html: $(syn) synopsis -f HTML -Wf,title="'BusyBox Documentation'" -o $@ $^ + +-include $(srctree)/Makefile.local From bugs at busybox.net Wed May 2 15:07:45 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 May 2007 15:07:45 -0700 Subject: [BusyBox 0001331]: override udhcp Message-ID: <523d6ce2068415b28b6b483c3051940d@busybox.net> The following issue has been CLOSED ====================================================================== http://busybox.net/bugs/view.php?id=1331 ====================================================================== Reported By: ncopa Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1331 Category: Networking Support Reproducibility: always Severity: minor Priority: normal Status: closed Resolution: open Fixed in Version: ====================================================================== Date Submitted: 05-02-2007 00:18 PDT Last Modified: 05-02-2007 15:07 PDT ====================================================================== Summary: override udhcp Description: applies 1.5.0 (product version above needs an update btw...) If udhcpc is enabled it is not possible to use other dhcp clients. I would be nice to be able to have a dhcp client in busybox but still be able to override it, runtime, if user find udhcp not be good enough. That is how it was in 1.4.x ====================================================================== ---------------------------------------------------------------------- vda - 05-02-07 15:07 ---------------------------------------------------------------------- Applied as rev 18544, thanks! Issue History Date Modified Username Field Change ====================================================================== 05-02-07 00:18 ncopa New Issue 05-02-07 00:18 ncopa Status new => assigned 05-02-07 00:18 ncopa Assigned To => BusyBox 05-02-07 15:07 vda Status assigned => closed 05-02-07 15:07 vda Note Added: 0002339 ====================================================================== From vda at busybox.net Wed May 2 15:22:23 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 15:22:23 -0700 (PDT) Subject: svn commit: trunk/busybox/networking Message-ID: <20070502222223.F1D6D485E9@busybox.net> Author: vda Date: 2007-05-02 15:22:23 -0700 (Wed, 02 May 2007) New Revision: 18546 Log: ifupdown: small optimization (avoid doing useless work if we are not going to update state file) Modified: trunk/busybox/networking/ifupdown.c Changeset: Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2007-05-02 22:07:03 UTC (rev 18545) +++ trunk/busybox/networking/ifupdown.c 2007-05-02 22:22:23 UTC (rev 18546) @@ -1239,8 +1239,10 @@ if (!okay && !FORCE) { bb_error_msg("ignoring unknown interface %s", liface); any_failures = 1; - } else { + } else if (!NO_ACT) { /* update the state file */ + FILE *state_fp; + llist_t *state; llist_t *state_list = read_iface_state(); llist_t *iface_state = find_iface_state(state_list, iface); @@ -1259,17 +1261,15 @@ } /* Actually write the new state */ - if (!NO_ACT) { - FILE *state_fp = xfopen("/var/run/ifstate", "w"); - llist_t *state = state_list; - while (state) { - if (state->data) { - fprintf(state_fp, "%s\n", state->data); - } - state = state->link; + state_fp = xfopen("/var/run/ifstate", "w"); + state = state_list; + while (state) { + if (state->data) { + fprintf(state_fp, "%s\n", state->data); } - fclose(state_fp); + state = state->link; } + fclose(state_fp); llist_free(state_list, free); } } From vda at busybox.net Wed May 2 16:01:33 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 16:01:33 -0700 (PDT) Subject: svn commit: trunk/busybox: applets libbb Message-ID: <20070502230133.51A77485EB@busybox.net> Author: vda Date: 2007-05-02 16:01:32 -0700 (Wed, 02 May 2007) New Revision: 18547 Log: fix suid config handling Modified: trunk/busybox/applets/applets.c trunk/busybox/libbb/xfuncs.c Changeset: Modified: trunk/busybox/applets/applets.c =================================================================== --- trunk/busybox/applets/applets.c 2007-05-02 22:22:23 UTC (rev 18546) +++ trunk/busybox/applets/applets.c 2007-05-02 23:01:32 UTC (rev 18547) @@ -110,9 +110,6 @@ /* Don't depend on the tools to combine strings. */ static const char config_file[] = "/etc/busybox.conf"; -/* There are 4 chars + 1 nul for each of user/group/other. */ -static const char mode_chars[] = "Ssx-\0Ssx-\0Ttx-"; - /* We don't supply a value for the nul, so an index adjustment is * necessary below. Also, we use unsigned short here to save some * space even though these are really mode_t values. */ @@ -257,6 +254,9 @@ e = skip_whitespace(e+1); for (i = 0; i < 3; i++) { + /* There are 4 chars + 1 nul for each of user/group/other. */ + static const char mode_chars[] = "Ssx-\0" "Ssx-\0" "Ttx-"; + const char *q; q = strchrnul(mode_chars + 5*i, *e++); if (!*q) { @@ -337,7 +337,8 @@ #if ENABLE_FEATURE_SUID static void check_suid(const struct bb_applet *applet) { - uid_t rgid; /* real gid */ + uid_t uid; + gid_t rgid; /* real gid */ if (ruid == 0) /* set by parse_config_file() */ return; /* run by root - no need to check more */ @@ -368,16 +369,24 @@ if (!(m & S_IXOTH)) /* is x bit not set ? */ bb_error_msg_and_die("you have no permission to run this applet!"); - if (sct->m_gid != 0) { - /* _both_ have to be set for sgid */ - if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - xsetgid(sct->m_gid); - } else xsetgid(rgid); /* no sgid -> drop */ - } - if (sct->m_uid != 0) { - if (sct->m_mode & S_ISUID) xsetuid(sct->m_uid); - else xsetuid(ruid); /* no suid -> drop */ - } + /* _both_ sgid and group_exec have to be set for setegid */ + if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) + rgid = sct->m_gid; + /* else (no setegid) we will set egid = rgid */ + + /* We set effective AND saved ids. If saved-id is not set + * like we do below, seteiud(0) can still later succeed! */ + if (setresgid(-1, rgid, rgid)) + bb_perror_msg_and_die("setresgid"); + + /* do we have to set effective uid? */ + uid = ruid; + if (sct->m_mode & S_ISUID) + uid = sct->m_uid; + /* else (no seteuid) we will set euid = ruid */ + + if (setresuid(-1, uid, uid)) + bb_perror_msg_and_die("setresuid"); return; } #if !ENABLE_FEATURE_SUID_CONFIG_QUIET @@ -393,6 +402,8 @@ #endif if (applet->need_suid == _BB_SUID_ALWAYS) { + /* Real uid is not 0. If euid isn't 0 too, suid bit + * is most probably not set on our executable */ if (geteuid()) bb_error_msg_and_die("applet requires root privileges!"); } else if (applet->need_suid == _BB_SUID_NEVER) { Modified: trunk/busybox/libbb/xfuncs.c =================================================================== --- trunk/busybox/libbb/xfuncs.c 2007-05-02 22:22:23 UTC (rev 18546) +++ trunk/busybox/libbb/xfuncs.c 2007-05-02 23:01:32 UTC (rev 18547) @@ -386,13 +386,13 @@ // setgid() will fail and we'll _still_be_root_, which is bad.) void xsetgid(gid_t gid) { - if (setgid(gid)) bb_error_msg_and_die("setgid"); + if (setgid(gid)) bb_perror_msg_and_die("setgid"); } // Die with an error message if we can't set uid. (See xsetgid() for why.) void xsetuid(uid_t uid) { - if (setuid(uid)) bb_error_msg_and_die("setuid"); + if (setuid(uid)) bb_perror_msg_and_die("setuid"); } // Return how long the file at fd is, if there's any way to determine it. From vda at busybox.net Wed May 2 16:39:04 2007 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 May 2007 16:39:04 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070502233904.8AE5E485E4@busybox.net> Author: vda Date: 2007-05-02 16:39:04 -0700 (Wed, 02 May 2007) New Revision: 18548 Log: hush: remove env builtin (it is buggy). Add comments Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-02 23:01:32 UTC (rev 18547) +++ trunk/busybox/shell/hush.c 2007-05-02 23:39:04 UTC (rev 18548) @@ -332,7 +332,6 @@ /* Index of subroutines: */ /* function prototypes for builtins */ static int builtin_cd(char **argv); -static int builtin_env(char **argv); static int builtin_eval(char **argv); static int builtin_exec(char **argv); static int builtin_exit(char **argv); @@ -432,7 +431,6 @@ { "break", "Exit for, while or until loop", builtin_not_written }, { "cd", "Change working directory", builtin_cd }, { "continue", "Continue for, while or until loop", builtin_not_written }, - { "env", "Print all environment variables", builtin_env }, { "eval", "Construct and run shell command", builtin_eval }, { "exec", "Exec command, replacing this shell with the exec'd process", builtin_exec }, @@ -643,19 +641,6 @@ return EXIT_SUCCESS; } -/* built-in 'env' handler */ -static int builtin_env(char **argv ATTRIBUTE_UNUSED) -{ -/* TODO: call env applet's code instead */ - char **e = environ; - if (e == NULL) - return EXIT_FAILURE; - while (*e) { - puts(*e++); - } - return EXIT_SUCCESS; -} - /* built-in 'exec' handler */ static int builtin_exec(char **argv) { @@ -670,13 +655,15 @@ { // TODO: bash does it ONLY on top-level sh exit (+interacive only?) //puts("exit"); /* bash does it */ +// TODO: warn if we have background jobs: "There are stopped jobs" +// On second consecutive 'exit', exit anyway. if (argv[1] == NULL) hush_exit(last_return_code); /* mimic bash: exit 123abc == exit 255 + error msg */ xfunc_error_retval = 255; /* bash: exit -2 == exit 254, no error msg */ - hush_exit(xatoi(argv[1])); + hush_exit(xatoi(argv[1]) & 0xff); } /* built-in 'export VAR=value' handler */ @@ -686,7 +673,15 @@ char *name = argv[1]; if (name == NULL) { - return builtin_env(argv); + // TODO: + // ash emits: export VAR='VAL' + // bash: declare -x VAR="VAL" + // (both also escape as needed (quotes, $, etc)) + char **e = environ; + if (e) + while (*e) + puts(*e++); + return EXIT_SUCCESS; } name = strdup(name); @@ -1321,6 +1316,8 @@ static void pseudo_exec(struct child_prog *child) { +// FIXME: buggy wrt NOMMU! Must not modify any global data +// until it does exec/_exit, but currently it does. int rcode; if (child->argv) { @@ -1852,6 +1849,8 @@ return -1; } +// NB: called by pseudo_exec, and therefore must not modify any +// global data until exec/_exit (we can be a child after vfork!) static int run_list_real(struct pipe *pi) { char *save_name = NULL; From bugs at busybox.net Thu May 3 11:44:48 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Thu, 3 May 2007 11:44:48 -0700 Subject: [BusyBox 0001329]: Patch for "util-linux/mdev.c": make it able to create symlinks and subdirectories Message-ID: <2cb3625163ebd8817cabccd6b3b7e55b@bugs.busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=1329 ====================================================================== Reported By: Souf Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1329 Category: New Features Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 04-29-2007 10:44 PDT Last Modified: 05-03-2007 11:44 PDT ====================================================================== Summary: Patch for "util-linux/mdev.c": make it able to create symlinks and subdirectories Description: This patch adds to mdev.c the ability to create symlinks and subdirectories: examples: stderr -> /proc/self/fd/2 pcmC[0-9]D[0-9]c 0:0 0666 >> /dev/snd/ 0755 modified files: util-linux/mdev.c util-linux/Config.in docs/mdev.txt The patch corrects also the bug 0001299 I wish that this patch be deeply tested before a possible integration ====================================================================== ---------------------------------------------------------------------- vapier - 05-02-07 10:57 ---------------------------------------------------------------------- you removed support for program execution which is not desirable i'll post a diff patch to the busybox mailing list we've been using in Blackfin/uClinux-dist ---------------------------------------------------------------------- Souf - 05-03-07 11:44 ---------------------------------------------------------------------- New patch for mdev.c which restores support for program execution Issue History Date Modified Username Field Change ====================================================================== 04-29-07 10:44 Souf New Issue 04-29-07 10:44 Souf Status new => assigned 04-29-07 10:44 Souf Assigned To => BusyBox 04-29-07 10:44 Souf File Added: mdev.patch 05-02-07 10:57 vapier Note Added: 0002336 05-03-07 11:44 Souf Note Added: 0002340 ====================================================================== From vda at busybox.net Thu May 3 15:45:40 2007 From: vda at busybox.net (vda at busybox.net) Date: Thu, 3 May 2007 15:45:40 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070503224540.BE2B0485D8@busybox.net> Author: vda Date: 2007-05-03 15:45:39 -0700 (Thu, 03 May 2007) New Revision: 18551 Log: hush: fix "true | exit 3; echo $?" bug Modified: trunk/busybox/shell/README trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/README =================================================================== --- trunk/busybox/shell/README 2007-05-03 09:33:24 UTC (rev 18550) +++ trunk/busybox/shell/README 2007-05-03 22:45:39 UTC (rev 18551) @@ -1,5 +1,18 @@ Various bits of what is known about busybox shells, in no particular order. +2007-05-03 +hush: update on "sleep 1 | exit 3; echo $?" bug. +parse_stream_outer() repeatedly calls parse_stream(). +parse_stream() is now fixed to stop on ';' in this example, +fixing it (parse_stream_outer() will call parse_stream() 1st time, +execute the parse tree, call parse_stream() 2nd time and execute the tree). +But it's not the end of story. +In more complex situations we _must_ parse way farther before executing. +Example #2: "{ sleep 1 | exit 3; echo $?; ...few_lines... } >file". +Because of redirection, we cannot execute 1st pipe before we parse it all. +We probably need to learn to store $var expressions in parse tree. +Debug printing of parse tree would be nice too. + 2007-04-28 hush: Ctrl-C and Ctrl-Z for single NOFORK commands are working. Memory and other resource leaks (opendir) are not addressed Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-03 09:33:24 UTC (rev 18550) +++ trunk/busybox/shell/hush.c 2007-05-03 22:45:39 UTC (rev 18551) @@ -89,6 +89,7 @@ /* Finer-grained debug switch */ #define debug_printf_jobs(...) do {} while (0) #define debug_printf_exec(...) do {} while (0) +#define debug_printf_parse(...) do {} while (0) #ifndef debug_printf @@ -111,7 +112,11 @@ #define debug_printf_exec(...) fprintf(stderr, __VA_ARGS__) #endif +#ifndef debug_printf_parse +#define debug_printf_parse(...) fprintf(stderr, __VA_ARGS__) +#endif + #if !ENABLE_HUSH_INTERACTIVE #undef ENABLE_FEATURE_EDITING #define ENABLE_FEATURE_EDITING 0 @@ -259,8 +264,14 @@ extern char **environ; /* This is in , but protected with __USE_GNU */ /* "globals" within this file */ +enum { + MAP_ORDINARY = 0, + MAP_FLOWTROUGH_IF_QUOTED = 1, + MAP_IFS_IF_UNQUOTED = 2, /* flow through if quoted too */ + MAP_NEVER_FLOWTROUGH = 3, +}; +static unsigned char map[256]; static const char *ifs; -static unsigned char map[256]; static int fake_mode; static struct close_me *close_me_head; static const char *cwd; @@ -390,13 +401,13 @@ /* primary string parsing: */ static int redirect_dup_num(struct in_str *input); static int redirect_opt_num(o_string *o); -static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end); +static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, const char *subst_end); static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch); static const char *lookup_param(const char *src); static char *make_string(char **inp); static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input); static int parse_string(o_string *dest, struct p_context *ctx, const char *src); -static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger); +static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger); /* setup: */ static int parse_stream_outer(struct in_str *inp, int flag); static int parse_string_outer(const char *s, int flag); @@ -1977,8 +1988,9 @@ { rcode = checkjobs(pi); } - debug_printf("checkjobs returned %d\n", rcode); + debug_printf_exec("checkjobs returned %d\n", rcode); } + debug_printf_exec("setting last_return_code=%d\n", rcode); last_return_code = rcode; pi->num_progs = save_num_progs; /* restore number of programs */ if (rmode == RES_IF || rmode == RES_ELIF) @@ -2519,7 +2531,7 @@ return 0; } -/* normal return is 0. +/* Normal return is 0. * Syntax or xglob errors return 1. */ static int done_word(o_string *dest, struct p_context *ctx) { @@ -2527,9 +2539,9 @@ glob_t *glob_target; int gr, flags = 0; - debug_printf("done_word: %s %p\n", dest->data, child); + debug_printf_parse("done_word: '%s' %p\n", dest->data, child); if (dest->length == 0 && !dest->nonnull) { - debug_printf(" true null, ignored\n"); + debug_printf_parse("done_word return 0: true null, ignored\n"); return 0; } if (ctx->pending_redirect) { @@ -2537,24 +2549,31 @@ } else { if (child->group) { syntax(); - return 1; /* syntax error, groups and arglists don't mix */ + debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); + return 1; } if (!child->argv && (ctx->type & FLAG_PARSE_SEMICOLON)) { - debug_printf("checking %s for reserved-ness\n", dest->data); - if (reserved_word(dest, ctx)) + debug_printf_parse(": checking %s for reserved-ness\n", dest->data); + if (reserved_word(dest, ctx)) { + debug_printf_parse("done_word return %d\n", (ctx->w == RES_SNTX)); return (ctx->w == RES_SNTX); + } } glob_target = &child->glob_result; if (child->argv) flags |= GLOB_APPEND; } gr = xglob(dest, flags, glob_target); - if (gr != 0) return 1; + if (gr != 0) { + debug_printf_parse("done_word return 1: xglob returned %d\n", gr); + return 1; + } b_reset(dest); if (ctx->pending_redirect) { ctx->pending_redirect = NULL; if (glob_target->gl_pathc != 1) { bb_error_msg("ambiguous redirect"); + debug_printf_parse("done_word return 1: ambiguous redirect\n"); return 1; } } else { @@ -2564,6 +2583,7 @@ done_word(dest, ctx); done_pipe(ctx, PIPE_SEQ); } + debug_printf_parse("done_word return 0\n"); return 0; } @@ -2614,7 +2634,7 @@ { struct pipe *new_p; done_command(ctx); /* implicit closure of previous command */ - debug_printf("done_pipe, type %d\n", type); + debug_printf_parse("done_pipe, type %d\n", type); ctx->pipe->followup = type; ctx->pipe->r_mode = ctx->w; new_p = new_pipe(); @@ -2710,7 +2730,8 @@ /* this version hacked for testing purposes */ /* return code is exit status of the process that is run. */ -static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end) +static int process_command_subs(o_string *dest, struct p_context *ctx, + struct in_str *input, const char *subst_end) { int retcode; o_string result = NULL_O_STRING; @@ -2732,7 +2753,7 @@ setup_file_in_str(&pipe_str, p); /* now send results of command back into original context */ - retcode = parse_stream(dest, ctx, &pipe_str, '\0'); + retcode = parse_stream(dest, ctx, &pipe_str, NULL); /* XXX In case of a syntax error, should we try to kill the child? * That would be tough to do right, so just read until EOF. */ if (retcode == 1) { @@ -2757,21 +2778,25 @@ static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch) { - int rcode, endch = 0; + int rcode; + const char *endch = NULL; struct p_context sub; struct child_prog *child = ctx->child; + + debug_printf_parse("parse_group entered\n"); if (child->argv) { syntax(); - return 1; /* syntax error, groups and arglists don't mix */ + debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); + return 1; } initialize_context(&sub); switch (ch) { case '(': - endch = ')'; + endch = ")"; child->subshell = 1; break; case '{': - endch = '}'; + endch = "}"; break; default: syntax(); /* really logic error */ @@ -2780,6 +2805,8 @@ done_word(dest, &sub); /* finish off the final word in the subcontext */ done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */ child->group = sub.list_head; + + debug_printf_parse("parse_group return %d\n", rcode); return rcode; /* child remains "open", available for possible redirects */ } @@ -2880,7 +2907,7 @@ break; case '(': b_getch(input); - process_command_subs(dest, ctx, input, ')'); + process_command_subs(dest, ctx, input, ")"); break; case '*': sep[0] = ifs[0]; @@ -2913,12 +2940,12 @@ { struct in_str foo; setup_string_in_str(&foo, src); - return parse_stream(dest, ctx, &foo, '\0'); + return parse_stream(dest, ctx, &foo, NULL); } /* return code is 0 for normal exit, 1 for syntax error */ static int parse_stream(o_string *dest, struct p_context *ctx, - struct in_str *input, int end_trigger) + struct in_str *input, const char *end_trigger) { int ch, m; int redir_fd; @@ -2929,30 +2956,38 @@ * A single-quote triggers a bypass of the main loop until its mate is * found. When recursing, quote state is passed in via dest->quote. */ - debug_printf("parse_stream, end_trigger=%d\n", end_trigger); + debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger); + while ((ch = b_getch(input)) != EOF) { m = map[ch]; next = (ch == '\n') ? 0 : b_peek(input); - debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n", + debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", ch, ch, m, dest->quote); - if (m == 0 || ((m == 1 || m == 2) && dest->quote)) { + if (m == MAP_ORDINARY + || (m != MAP_NEVER_FLOWTROUGH && dest->quote) + ) { b_addqchr(dest, ch, dest->quote); continue; } - if (m == 2) { /* unquoted IFS */ + if (m == MAP_IFS_IF_UNQUOTED) { if (done_word(dest, ctx)) { + debug_printf_parse("parse_stream return 1\n"); return 1; } - /* If we aren't performing a substitution, treat a newline as a - * command separator. */ - if (end_trigger != '\0' && ch == '\n') + /* If we aren't performing a substitution, treat + * a newline as a command separator. + * [why we don't handle it exactly like ';'? --vda] */ + if (end_trigger && ch == '\n') { done_pipe(ctx, PIPE_SEQ); + } } - if (ch == end_trigger && !dest->quote && ctx->w == RES_NONE) { - debug_printf("leaving parse_stream (triggered)\n"); + if ((end_trigger && strchr(end_trigger, ch)) + && !dest->quote && ctx->w == RES_NONE + ) { + debug_printf_parse("parse_stream return 0\n"); return 0; } - if (m == 2) + if (m == MAP_IFS_IF_UNQUOTED) continue; switch (ch) { case '#': @@ -2970,13 +3005,17 @@ case '\\': if (next == EOF) { syntax(); + debug_printf_parse("parse_stream return 1\n"); return 1; } b_addqchr(dest, '\\', dest->quote); b_addqchr(dest, b_getch(input), dest->quote); break; case '$': - if (handle_dollar(dest, ctx, input) != 0) return 1; + if (handle_dollar(dest, ctx, input) != 0) { + debug_printf_parse("parse_stream return 1: handle_dollar returned non-0\n"); + return 1; + } break; case '\'': dest->nonnull = 1; @@ -2988,6 +3027,7 @@ } if (ch == EOF) { syntax(); + debug_printf_parse("parse_stream return 1\n"); return 1; } break; @@ -2996,7 +3036,7 @@ dest->quote = !dest->quote; break; case '`': - process_command_subs(dest, ctx, input, '`'); + process_command_subs(dest, ctx, input, "`"); break; case '>': redir_fd = redirect_opt_num(dest); @@ -3007,6 +3047,7 @@ b_getch(input); } else if (next == '(') { syntax(); /* until we support >(list) Process Substitution */ + debug_printf_parse("parse_stream return 1: >(process) not supported\n"); return 1; } setup_redirect(ctx, redir_fd, redir_style, input); @@ -3023,6 +3064,7 @@ b_getch(input); } else if (next == '(') { syntax(); /* until we support <(list) Process Substitution */ + debug_printf_parse("parse_stream return 1: <(process) not supported\n"); return 1; } setup_redirect(ctx, redir_fd, redir_style, input); @@ -3054,28 +3096,32 @@ break; case '(': case '{': - if (parse_group(dest, ctx, input, ch) != 0) + if (parse_group(dest, ctx, input, ch) != 0) { + debug_printf_parse("parse_stream return 1: parse_group returned non-0\n"); return 1; + } break; case ')': case '}': - syntax(); /* Proper use of this character caught by end_trigger */ + syntax(); /* Proper use of this character is caught by end_trigger */ + debug_printf_parse("parse_stream return 1: unexpected '}'\n"); return 1; default: syntax(); /* this is really an internal logic error */ + debug_printf_parse("parse_stream return 1: internal logic error\n"); return 1; } } - /* complain if quote? No, maybe we just finished a command substitution + /* Complain if quote? No, maybe we just finished a command substitution * that was quoted. Example: * $ echo "`cat foo` plus more" * and we just got the EOF generated by the subshell that ran "cat foo" - * The only real complaint is if we got an EOF when end_trigger != '\0', + * The only real complaint is if we got an EOF when end_trigger != NULL, * that is, we were really supposed to get end_trigger, and never got * one before the EOF. Can't use the standard "syntax error" return code, * so that parse_stream_outer can distinguish the EOF and exit smoothly. */ - debug_printf("leaving parse_stream (EOF)\n"); - if (end_trigger != '\0') + debug_printf_parse("parse_stream return -%d\n", end_trigger != NULL); + if (end_trigger) return -1; return 0; } @@ -3097,17 +3143,17 @@ * The map[] array only really needs two bits each, and on most machines * that would be faster because of the reduced L1 cache footprint. */ - memset(map, 0, sizeof(map)); /* most characters flow through always */ - mapset("\\$'\"`", 3); /* never flow through */ - mapset("<>;&|(){}#", 1); /* flow through if quoted */ - mapset(ifs, 2); /* also flow through if quoted */ + memset(map, MAP_ORDINARY, sizeof(map)); /* most chars flow through always */ + mapset("\\$'\"`", MAP_NEVER_FLOWTROUGH); + mapset("<>;&|(){}#", MAP_FLOWTROUGH_IF_QUOTED); + mapset(ifs, MAP_IFS_IF_UNQUOTED); /* also flow through if quoted */ } /* most recursion does not come through here, the exception is * from builtin_source() */ static int parse_stream_outer(struct in_str *inp, int flag) { -// FIXME: 'true | exit 3; echo $?' is parsed as a whole, +// FIXME: '{ true | exit 3; echo $? }' is parsed as a whole, // as a result $? is replaced by 0, not 3! // Need to stop & execute stuff at ';', not parse till EOL! @@ -3119,11 +3165,11 @@ initialize_context(&ctx); update_ifs_map(); if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) - mapset(";$&|", 0); + mapset(";$&|", MAP_ORDINARY); #if ENABLE_HUSH_INTERACTIVE inp->promptmode = 1; #endif - rcode = parse_stream(&temp, &ctx, inp, '\n'); + rcode = parse_stream(&temp, &ctx, inp, ";\n"); if (rcode != 1 && ctx.old_flag != 0) { syntax(); } From vda at busybox.net Thu May 3 15:57:56 2007 From: vda at busybox.net (vda at busybox.net) Date: Thu, 3 May 2007 15:57:56 -0700 (PDT) Subject: svn commit: trunk/busybox/editors Message-ID: <20070503225756.E3C75485D9@busybox.net> Author: vda Date: 2007-05-03 15:57:56 -0700 (Thu, 03 May 2007) New Revision: 18552 Log: awk: guard against empty environment Modified: trunk/busybox/editors/awk.c Changeset: Modified: trunk/busybox/editors/awk.c =================================================================== --- trunk/busybox/editors/awk.c 2007-05-03 22:45:39 UTC (rev 18551) +++ trunk/busybox/editors/awk.c 2007-05-03 22:57:56 UTC (rev 18552) @@ -2696,7 +2696,8 @@ newfile("/dev/stdout")->F = stdout; newfile("/dev/stderr")->F = stderr; - for (envp = environ; *envp; envp++) { + /* Huh, people report that sometimes environ is NULL. Oh well. */ + if (environ) for (envp = environ; *envp; envp++) { char *s = xstrdup(*envp); char *s1 = strchr(s, '='); if (s1) { From vda at busybox.net Thu May 3 16:39:37 2007 From: vda at busybox.net (vda at busybox.net) Date: Thu, 3 May 2007 16:39:37 -0700 (PDT) Subject: svn commit: trunk/busybox/networking/udhcp Message-ID: <20070503233937.9DFEE485B6@busybox.net> Author: vda Date: 2007-05-03 16:39:35 -0700 (Thu, 03 May 2007) New Revision: 18554 Log: udhcpc: stop deleting our own pidfile if we daemonize. udhcp[cd]: stop using atexit magic fir pidfile removal. Modified: trunk/busybox/networking/udhcp/common.c trunk/busybox/networking/udhcp/dhcpc.c trunk/busybox/networking/udhcp/dhcpd.c Changeset: Modified: trunk/busybox/networking/udhcp/common.c =================================================================== --- trunk/busybox/networking/udhcp/common.c 2007-05-03 23:13:04 UTC (rev 18553) +++ trunk/busybox/networking/udhcp/common.c 2007-05-03 23:39:35 UTC (rev 18554) @@ -24,16 +24,6 @@ return info.uptime; } -#if ENABLE_FEATURE_PIDFILE -static const char *saved_pidfile; - -static void pidfile_delete(void) -{ - if (saved_pidfile) - remove_pidfile(saved_pidfile); -} -#endif - static void create_pidfile(const char *pidfile) { if (!pidfile) @@ -43,12 +33,6 @@ bb_perror_msg("cannot create pidfile %s", pidfile); return; } -#if ENABLE_FEATURE_PIDFILE - /* lockf(pid_fd, F_LOCK, 0); */ - if (!saved_pidfile) - atexit(pidfile_delete); - saved_pidfile = pidfile; -#endif } void udhcp_make_pidfile(const char *pidfile) Modified: trunk/busybox/networking/udhcp/dhcpc.c =================================================================== --- trunk/busybox/networking/udhcp/dhcpc.c 2007-05-03 23:13:04 UTC (rev 18553) +++ trunk/busybox/networking/udhcp/dhcpc.c 2007-05-03 23:39:35 UTC (rev 18554) @@ -116,6 +116,9 @@ #else // chdir(/) is problematic. Imagine that e.g. pidfile name is RELATIVE! what will unlink do then, eh? bb_daemonize(DAEMON_CHDIR_ROOT); + /* rewrite pidfile, as our pid is different now */ + if (client_config.pidfile) + write_pidfile(client_config.pidfile); logmode &= ~LOGMODE_STDIO; #endif client_config.foreground = 1; /* Do not fork again. */ @@ -327,7 +330,8 @@ client_background(); } else if (client_config.abort_if_no_lease) { bb_info_msg("No lease, failing"); - return 1; + retval = 1; + goto ret; } /* wait to try again */ packet_num = 0; @@ -483,7 +487,7 @@ if (client_config.quit_after_lease) { if (client_config.release_on_quit) perform_release(); - return 0; + goto ret0; } if (!client_config.foreground) client_background(); @@ -516,7 +520,7 @@ bb_info_msg("Received SIGTERM"); if (client_config.release_on_quit) perform_release(); - return 0; + goto ret0; } } else if (retval == -1 && errno == EINTR) { /* a signal was caught */ @@ -524,7 +528,11 @@ /* An error occured */ bb_perror_msg("select"); } - - } - return 0; + } /* for (;;) */ + ret0: + retval = 0; + ret: + if (client_config.pidfile) + remove_pidfile(client_config.pidfile); + return retval; } Modified: trunk/busybox/networking/udhcp/dhcpd.c =================================================================== --- trunk/busybox/networking/udhcp/dhcpd.c 2007-05-03 23:13:04 UTC (rev 18553) +++ trunk/busybox/networking/udhcp/dhcpd.c 2007-05-03 23:39:35 UTC (rev 18554) @@ -53,11 +53,11 @@ udhcp_make_pidfile(server_config.pidfile); option = find_option(server_config.options, DHCP_LEASE_TIME); + server_config.lease = LEASE_TIME; if (option) { memcpy(&server_config.lease, option->data + 2, 4); server_config.lease = ntohl(server_config.lease); - } else - server_config.lease = LEASE_TIME; + } /* Sanity check */ num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; @@ -72,8 +72,10 @@ read_leases(server_config.lease_file); if (read_interface(server_config.interface, &server_config.ifindex, - &server_config.server, server_config.arp) < 0) - return 1; + &server_config.server, server_config.arp) < 0) { + retval = 1; + goto ret; + } /* Setup the signal pipe */ udhcp_sp_setup(); @@ -82,7 +84,8 @@ while (1) { /* loop until universe collapses */ if (server_socket < 0) { - server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface); + server_socket = listen_socket(INADDR_ANY, SERVER_PORT, + server_config.interface); } max_sock = udhcp_sp_fd_set(&rfds, server_socket); @@ -90,16 +93,17 @@ tv.tv_sec = timeout_end - time(0); tv.tv_usec = 0; } + retval = 0; if (!server_config.auto_time || tv.tv_sec > 0) { retval = select(max_sock + 1, &rfds, NULL, NULL, server_config.auto_time ? &tv : NULL); - } else retval = 0; /* If we already timed out, fall through */ - + } if (retval == 0) { write_leases(); timeout_end = time(0) + server_config.auto_time; continue; - } else if (retval < 0 && errno != EINTR) { + } + if (retval < 0 && errno != EINTR) { DEBUG("error on select"); continue; } @@ -113,7 +117,7 @@ continue; case SIGTERM: bb_info_msg("Received a SIGTERM"); - return 0; + goto ret0; case 0: break; /* no signal */ default: continue; /* signal or error (probably EINTR) */ } @@ -222,7 +226,8 @@ break; case DHCPRELEASE: DEBUG("Received RELEASE"); - if (lease) lease->expires = time(0); + if (lease) + lease->expires = time(0); break; case DHCPINFORM: DEBUG("Received INFORM"); @@ -232,6 +237,10 @@ bb_info_msg("Unsupported DHCP message (%02x) - ignoring", state[0]); } } - - return 0; + ret0: + retval = 0; + ret: + if (server_config.pidfile) + remove_pidfile(server_config.pidfile); + return retval; } From bugs at busybox.net Thu May 3 19:20:10 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Thu, 3 May 2007 19:20:10 -0700 Subject: [BusyBox 0001332]: powerpc-603, gcc-4.1.1-glibc-2.3.6 build failures Message-ID: <99959c0cc18274f4b0a9ad4586c1aa4b@bugs.busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=1332 ====================================================================== Reported By: jfree Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1332 Category: Other Reproducibility: always Severity: major Priority: normal Status: assigned ====================================================================== Date Submitted: 05-03-2007 19:20 PDT Last Modified: 05-03-2007 19:20 PDT ====================================================================== Summary: powerpc-603, gcc-4.1.1-glibc-2.3.6 build failures Description: 1.4.2 build failures using gcc-4.1.1-glibc-2.3.6 powerpc-603 tools kludged up patch attached - needs closer look cc1: warnings being treated as errors coreutils/md5_sha1_sum.c: In function 'hash_bin_to_hex': coreutils/md5_sha1_sum.c:24: warning: pointer targets in return differ in signedness In file included from findutils/find.c:49: /work/p4/NAS/NetHDD_G2/gcc-4.1.1-glibc-2.3.6/powerpc-603-linux-gnu/powerpc-603-linux-gnu/sys-root/usr/include/fnmatch.h:47:1: error: "FNM_LEADING_DIR" redefined In file included from include/libbb.h:13, from include/busybox.h:10, from findutils/find.c:48: include/platform.h:223:1: error: this is the location of the previous definition miscutils/less.c: In function 'less_main': miscutils/less.c:1213: warning: pointer targets in passing argument 2 of 'get_terminal_width_height' differ in signedness miscutils/less.c:1213: warning: pointer targets in passing argument 3 of 'get_terminal_width_height' differ in signedness networking/interface.c: In function 'in_ether': networking/interface.c:853: warning: pointer targets in assignment differ in signedness ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 05-03-07 19:20 jfree New Issue 05-03-07 19:20 jfree Status new => assigned 05-03-07 19:20 jfree Assigned To => BusyBox 05-03-07 19:20 jfree File Added: diff ====================================================================== From vda at busybox.net Fri May 4 06:07:28 2007 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 May 2007 06:07:28 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070504130728.3504848074@busybox.net> Author: vda Date: 2007-05-04 06:07:27 -0700 (Fri, 04 May 2007) New Revision: 18555 Log: hush: add parse tree debug print Modified: trunk/busybox/shell/README trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/README =================================================================== --- trunk/busybox/shell/README 2007-05-03 23:39:35 UTC (rev 18554) +++ trunk/busybox/shell/README 2007-05-04 13:07:27 UTC (rev 18555) @@ -1,6 +1,10 @@ Various bits of what is known about busybox shells, in no particular order. 2007-05-03 +hush: new bug spotted: Ctrl-C on "while true; do true; done" kills shell, +not just the loop. + +2007-05-03 hush: update on "sleep 1 | exit 3; echo $?" bug. parse_stream_outer() repeatedly calls parse_stream(). parse_stream() is now fixed to stop on ';' in this example, Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-03 23:39:35 UTC (rev 18554) +++ trunk/busybox/shell/hush.c 2007-05-04 13:07:27 UTC (rev 18555) @@ -85,11 +85,12 @@ /* If you comment out one of these below, it will be #defined later * to perform debug printfs to stderr: */ -#define debug_printf(...) do {} while (0) -/* Finer-grained debug switch */ -#define debug_printf_jobs(...) do {} while (0) -#define debug_printf_exec(...) do {} while (0) +#define debug_printf(...) do {} while (0) +/* Finer-grained debug switches */ +#define debug_printf_jobs(...) do {} while (0) +#define debug_printf_exec(...) do {} while (0) #define debug_printf_parse(...) do {} while (0) +#define debug_print_tree(a, b) do {} while (0) #ifndef debug_printf @@ -1860,6 +1861,61 @@ return -1; } +#ifndef debug_print_tree +static void debug_print_tree(struct pipe *pi, int lvl) +{ + static const char *PIPE[] = { + [PIPE_SEQ] = "SEQ", + [PIPE_AND] = "AND", + [PIPE_OR ] = "OR", + [PIPE_BG ] = "BG", + }; + static const char *RES[] = { + [RES_NONE ] = "NONE" , + [RES_IF ] = "IF" , + [RES_THEN ] = "THEN" , + [RES_ELIF ] = "ELIF" , + [RES_ELSE ] = "ELSE" , + [RES_FI ] = "FI" , + [RES_FOR ] = "FOR" , + [RES_WHILE] = "WHILE", + [RES_UNTIL] = "UNTIL", + [RES_DO ] = "DO" , + [RES_DONE ] = "DONE" , + [RES_XXXX ] = "XXXX" , + [RES_IN ] = "IN" , + [RES_SNTX ] = "SNTX" , + }; + + int pin, prn; + char **argv; + pin = 0; + while (pi) { + fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "", + pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]); + prn = 0; + while (prn < pi->num_progs) { + fprintf(stderr, "%*s prog %d", lvl*2, "", prn); + if (pi->progs[prn].group) { + fprintf(stderr, " group: (argv=%p)\n", pi->progs[prn].argv); + debug_print_tree(pi->progs[prn].group, lvl+1); + prn++; + continue; + } + argv = pi->progs[prn].argv; + if (argv) while (*argv) { + fprintf(stderr, " '%s'", *argv); + argv++; + } + fprintf(stderr, "\n"); + prn++; + } + pi = pi->next; + pin++; + } +} +#endif + // NB: called by pseudo_exec, and therefore must not modify any // global data until exec/_exit (we can be a child after vfork!) static int run_list_real(struct pipe *pi) @@ -2088,7 +2144,7 @@ /* free_pipe_list has the side effect of clearing memory * In the long run that function can be merged with run_list_real, * but doing that now would hobble the debugging effort. */ - free_pipe_list(pi,0); + free_pipe_list(pi, 0); return rcode; } @@ -3177,6 +3233,7 @@ done_word(&temp, &ctx); done_pipe(&ctx, PIPE_SEQ); debug_printf_exec("parse_stream_outer: run_list\n"); + debug_print_tree(ctx.list_head, 0); run_list(ctx.list_head); } else { if (ctx.old_flag != 0) { From vda at busybox.net Fri May 4 07:54:38 2007 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 May 2007 07:54:38 -0700 (PDT) Subject: svn commit: trunk/busybox: applets shell Message-ID: <20070504145438.0EB1D48093@busybox.net> Author: vda Date: 2007-05-04 07:54:36 -0700 (Fri, 04 May 2007) New Revision: 18557 Log: applets: fix compile-time warning Modified: trunk/busybox/applets/applets.c trunk/busybox/shell/README Changeset: Modified: trunk/busybox/applets/applets.c =================================================================== --- trunk/busybox/applets/applets.c 2007-05-04 14:13:17 UTC (rev 18556) +++ trunk/busybox/applets/applets.c 2007-05-04 14:54:36 UTC (rev 18557) @@ -337,7 +337,6 @@ #if ENABLE_FEATURE_SUID static void check_suid(const struct bb_applet *applet) { - uid_t uid; gid_t rgid; /* real gid */ if (ruid == 0) /* set by parse_config_file() */ @@ -346,6 +345,7 @@ #if ENABLE_FEATURE_SUID_CONFIG if (suid_cfg_readable) { + uid_t uid; struct BB_suid_config *sct; mode_t m; Modified: trunk/busybox/shell/README =================================================================== --- trunk/busybox/shell/README 2007-05-04 14:13:17 UTC (rev 18556) +++ trunk/busybox/shell/README 2007-05-04 14:54:36 UTC (rev 18557) @@ -1,8 +1,13 @@ Various bits of what is known about busybox shells, in no particular order. 2007-05-03 -hush: new bug spotted: Ctrl-C on "while true; do true; done" kills shell, -not just the loop. +hush: new bug spotted: Ctrl-C on "while true; do true; done" doesn't +work right: +# while true; do true; done +[1] 0 true <-- pressing Ctrl-C several times... +[2] 0 true +[3] 0 true +Segmentation fault 2007-05-03 hush: update on "sleep 1 | exit 3; echo $?" bug. From bugs at busybox.net Fri May 4 09:50:44 2007 From: bugs at busybox.net (bugs at busybox.net) Date: Fri, 4 May 2007 09:50:44 -0700 Subject: [BusyBox 0001333]: "fdisk -l" (lower case ell) does not read partition table correctly Message-ID: <6bbe6a186054b19906580301741381d5@bugs.busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=1333 ====================================================================== Reported By: kiltedknight Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 1333 Category: Other Reproducibility: always Severity: major Priority: normal Status: assigned ====================================================================== Date Submitted: 05-04-2007 09:50 PDT Last Modified: 05-04-2007 09:50 PDT ====================================================================== Summary: "fdisk -l" (lower case ell) does not read partition table correctly Description: When running "busybox fdisk -l" against a known disk, I get the following: Warning: ignoring extra data in partition table 5 Warning: ignoring extra data in partition table 5 Warning: ignoring extra data in partition table 6 Warning: ignoring extra data in partition table 6 Warning: ignoring extra data in partition table 6 Warning: invalid flag 0xe4,0x0f of partition table 5 will be corrected by w(rite) Warning: invalid flag 0x36,0xb0 of partition table 6 will be corrected by w(rite) Disk /dev/hde: 20.0 GB, 20020396032 bytes 255 heads, 63 sectors/track, 2434 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/hde1 * 1 33 265041 83 Linux /dev/hde2 34 925 7164990 83 Linux /dev/hde3 926 1186 2096482+ 82 Linux swap /dev/hde4 1187 2434 10024560 5 Extended /dev/hde5 ? 17782 15955 2132811720 3f Unknown /dev/hde6 ? 101267 247811 1177113252+ 11 Hidden FAT12 If I run the linux "fdisk -l", I get this: Disk /dev/hde: 20.0 GB, 20020396032 bytes 255 heads, 63 sectors/track, 2434 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/hde1 * 1 33 265041 83 Linux /dev/hde2 34 925 7164990 83 Linux /dev/hde3 926 1186 2096482+ 82 Linux swap / Solaris /dev/hde4 1187 2434 10024560 5 Extended /dev/hde5 1187 1377 1534176 83 Linux /dev/hde6 1378 2434 8490321 83 Linux It looks like it's having problems reading the partitions out of an extended partition. ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 05-04-07 09:50 kiltedknight New Issue 05-04-07 09:50 kiltedknight Status new => assigned 05-04-07 09:50 kiltedknight Assigned To => BusyBox ====================================================================== From vda at busybox.net Fri May 4 14:37:42 2007 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 May 2007 14:37:42 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070504213742.9D0F84808E@busybox.net> Author: vda Date: 2007-05-04 14:37:27 -0700 (Fri, 04 May 2007) New Revision: 18558 Log: hush: fix "while true; do true; done" + ctrl-z Modified: trunk/busybox/shell/README trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/README =================================================================== --- trunk/busybox/shell/README 2007-05-04 14:54:36 UTC (rev 18557) +++ trunk/busybox/shell/README 2007-05-04 21:37:27 UTC (rev 18558) @@ -1,5 +1,8 @@ Various bits of what is known about busybox shells, in no particular order. +2007-05-04 +hush: make ctrl-Z/C work correctly for "while true; do true; done" + 2007-05-03 hush: new bug spotted: Ctrl-C on "while true; do true; done" doesn't work right: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-04 14:54:36 UTC (rev 18557) +++ trunk/busybox/shell/hush.c 2007-05-04 21:37:27 UTC (rev 18558) @@ -468,7 +468,6 @@ #if ENABLE_HUSH_JOB -#if ENABLE_FEATURE_SH_STANDALONE /* move to libbb? */ static void signal_SA_RESTART(int sig, void (*handler)(int)) { @@ -478,7 +477,6 @@ sigemptyset(&sa.sa_mask); sigaction(sig, &sa, NULL); } -#endif /* Signals are grouped, we handle them in batches */ static void set_fatal_sighandler(void (*handler)(int)) @@ -508,7 +506,6 @@ } /* SIGCHLD is special and handled separately */ -#if ENABLE_FEATURE_SH_STANDALONE static void set_every_sighandler(void (*handler)(int)) { set_fatal_sighandler(handler); @@ -517,53 +514,57 @@ signal(SIGCHLD, handler); } -static struct pipe *nofork_pipe; +static struct pipe *toplevel_list; +static sigjmp_buf toplevel_jb; +smallint ctrl_z_flag; +#if ENABLE_FEATURE_SH_STANDALONE struct nofork_save_area nofork_save; -static sigjmp_buf nofork_jb; +#endif static void handler_ctrl_c(int sig) { debug_printf_jobs("got sig %d\n", sig); // as usual we can have all kinds of nasty problems with leaked malloc data here - siglongjmp(nofork_jb, 1); + siglongjmp(toplevel_jb, 1); } static void handler_ctrl_z(int sig) { pid_t pid; - debug_printf_jobs("got tty sig %d\n", sig); + debug_printf_jobs("got tty sig %d in pid %d\n", sig, getpid()); pid = fork(); - if (pid < 0) /* can't fork. Pretend there were no Ctrl-Z */ + if (pid < 0) /* can't fork. Pretend there were no ctrl-Z */ return; - debug_printf_jobs("bg'ing nofork\n"); - nofork_save.saved = 0; /* flag the fact that Ctrl-Z was handled */ - nofork_pipe->running_progs = 1; - nofork_pipe->stopped_progs = 0; + ctrl_z_flag = 1; +//vda: wrong!! +// toplevel_list->running_progs = 1; +// toplevel_list->stopped_progs = 0; +// if (!pid) { /* child */ - debug_printf_jobs("setting pgrp for child\n"); setpgrp(); + debug_printf_jobs("set pgrp for child %d ok\n", getpid()); set_every_sighandler(SIG_DFL); raise(SIGTSTP); /* resend TSTP so that child will be stopped */ - debug_printf_jobs("returning to child\n"); + debug_printf_jobs("returning in child\n"); /* return to nofork, it will eventually exit now, * not return back to shell */ return; } /* parent */ /* finish filling up pipe info */ - nofork_pipe->pgrp = pid; /* child is in its own pgrp */ - nofork_pipe->progs[0].pid = pid; - nofork_pipe->running_progs = 1; - nofork_pipe->stopped_progs = 0; + toplevel_list->pgrp = pid; /* child is in its own pgrp */ + toplevel_list->progs[0].pid = pid; +//vda: wrong!! +// toplevel_list->running_progs = 1; +// toplevel_list->stopped_progs = 0; /* parent needs to longjmp out of running nofork. * we will "return" exitcode 0, with child put in background */ // as usual we can have all kinds of nasty problems with leaked malloc data here - siglongjmp(nofork_jb, 1); + debug_printf_jobs("siglongjmp in parent\n"); + siglongjmp(toplevel_jb, 1); } -#endif - /* Restores tty foreground process group, and exits. * May be called as signal handler for fatal signal * (will faithfully resend signal to itself, producing correct exit state) @@ -1039,6 +1040,7 @@ } #if ENABLE_HUSH_INTERACTIVE +#if ENABLE_FEATURE_EDITING static void cmdedit_set_initial_prompt(void) { #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT @@ -1049,6 +1051,7 @@ PS1 = "\\w \\$ "; #endif } +#endif static const char* setup_prompt_string(int promptmode) { @@ -1072,7 +1075,7 @@ debug_printf("result %s\n", prompt_str); return prompt_str; } -#endif +#endif /* ENABLE_HUSH_INTERACTIVE */ #if ENABLE_FEATURE_EDITING static line_input_t *line_input_state; @@ -1470,7 +1473,7 @@ /* Do we do this right? * bash-3.00# sleep 20 | false - * + * * [3]+ Stopped sleep 20 | false * bash-3.00# echo $? * 1 <========== bg pipe is not fully done, but exitcode is already known! @@ -1590,43 +1593,6 @@ } #endif -#if ENABLE_FEATURE_SH_STANDALONE -/* run_pipe_real's helper */ -static int run_single_fg_nofork(struct pipe *pi, const struct bb_applet *a, - char **argv) -{ -#if ENABLE_HUSH_JOB - int rcode; - /* TSTP handler will store pid etc in pi */ - nofork_pipe = pi; - save_nofork_data(&nofork_save); - if (sigsetjmp(nofork_jb, 1) == 0) { - signal_SA_RESTART(SIGTSTP, handler_ctrl_z); - signal(SIGINT, handler_ctrl_c); - rcode = run_nofork_applet_prime(&nofork_save, a, argv); - if (--nofork_save.saved != 0) { - /* Ctrl-Z forked, we are child */ - exit(rcode); - } - return rcode; - } - /* Ctrl-Z forked, we are parent; or Ctrl-C. - * Sighandler has longjmped us here */ - signal(SIGINT, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - debug_printf_jobs("Exiting nofork early\n"); - restore_nofork_data(&nofork_save); - if (nofork_save.saved == 0) /* Ctrl-Z, not Ctrl-C */ - insert_bg_job(pi); - else - putchar('\n'); /* bash does this on Ctrl-C */ - return 0; -#else - return run_nofork_applet(a, argv); -#endif -} -#endif - /* run_pipe_real() starts all the jobs, but doesn't wait for anything * to finish. See checkjobs(). * @@ -1662,7 +1628,7 @@ #if ENABLE_HUSH_JOB pi->pgrp = -1; #endif - pi->running_progs = 0; + pi->running_progs = 1; pi->stopped_progs = 0; /* Check if this is a simple builtin (not part of a pipe). @@ -1673,8 +1639,6 @@ if (single_fg && child->group && child->subshell == 0) { debug_printf("non-subshell grouping\n"); setup_redirects(child, squirrel); - /* XXX could we merge code with following builtin case, - * by creating a pseudo builtin that calls run_list_real? */ debug_printf_exec(": run_list_real\n"); rcode = run_list_real(child->group); restore_redirects(squirrel); @@ -1758,8 +1722,9 @@ const struct bb_applet *a = find_applet_by_name(argv[i]); if (a && a->nofork) { setup_redirects(child, squirrel); - debug_printf_exec(": run_single_fg_nofork '%s' '%s'...\n", argv[i], argv[i+1]); - rcode = run_single_fg_nofork(pi, a, argv + i); + debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv[i], argv[i+1]); + save_nofork_data(&nofork_save); + rcode = run_nofork_applet_prime(&nofork_save, a, argv); restore_redirects(squirrel); debug_printf_exec("run_pipe_real return %d\n", rcode); return rcode; @@ -1769,6 +1734,7 @@ } /* Going to fork a child per each pipe member */ + pi->running_progs = 0; /* Disable job control signals for shell (parent) and * for initial child code after fork */ @@ -1865,26 +1831,26 @@ static void debug_print_tree(struct pipe *pi, int lvl) { static const char *PIPE[] = { - [PIPE_SEQ] = "SEQ", - [PIPE_AND] = "AND", - [PIPE_OR ] = "OR", - [PIPE_BG ] = "BG", + [PIPE_SEQ] = "SEQ", + [PIPE_AND] = "AND", + [PIPE_OR ] = "OR", + [PIPE_BG ] = "BG", }; static const char *RES[] = { - [RES_NONE ] = "NONE" , - [RES_IF ] = "IF" , - [RES_THEN ] = "THEN" , - [RES_ELIF ] = "ELIF" , - [RES_ELSE ] = "ELSE" , - [RES_FI ] = "FI" , - [RES_FOR ] = "FOR" , - [RES_WHILE] = "WHILE", - [RES_UNTIL] = "UNTIL", - [RES_DO ] = "DO" , - [RES_DONE ] = "DONE" , - [RES_XXXX ] = "XXXX" , - [RES_IN ] = "IN" , - [RES_SNTX ] = "SNTX" , + [RES_NONE ] = "NONE" , + [RES_IF ] = "IF" , + [RES_THEN ] = "THEN" , + [RES_ELIF ] = "ELIF" , + [RES_ELSE ] = "ELSE" , + [RES_FI ] = "FI" , + [RES_FOR ] = "FOR" , + [RES_WHILE] = "WHILE", + [RES_UNTIL] = "UNTIL", + [RES_DO ] = "DO" , + [RES_DONE ] = "DONE" , + [RES_XXXX ] = "XXXX" , + [RES_IN ] = "IN" , + [RES_SNTX ] = "SNTX" , }; int pin, prn; @@ -1897,7 +1863,9 @@ while (prn < pi->num_progs) { fprintf(stderr, "%*s prog %d", lvl*2, "", prn); if (pi->progs[prn].group) { - fprintf(stderr, " group: (argv=%p)\n", pi->progs[prn].argv); + fprintf(stderr, " group %s: (argv=%p)\n", + (pi->subshell ? "()" : "{}"), + pi->progs[prn].argv); debug_print_tree(pi->progs[prn].group, lvl+1); prn++; continue; @@ -1920,18 +1888,25 @@ // global data until exec/_exit (we can be a child after vfork!) static int run_list_real(struct pipe *pi) { +#if ENABLE_HUSH_JOB + static int level; +#else + enum { level = 0 }; +#endif + char *save_name = NULL; char **list = NULL; char **save_list = NULL; struct pipe *rpipe; int flag_rep = 0; int save_num_progs; - int rcode = 0, flag_skip = 1; + int flag_skip = 1; + int rcode = 0; /* probaly for gcc only */ int flag_restore = 0; int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; - debug_printf_exec("run_list_real start:\n"); + debug_printf_exec("run_list_real start lvl %d\n", level + 1); /* check syntax for "for" */ for (rpipe = pi; rpipe; rpipe = rpipe->next) { @@ -1939,17 +1914,60 @@ && (rpipe->next == NULL) ) { syntax(); - debug_printf_exec("run_list_real return 1\n"); + debug_printf_exec("run_list_real lvl %d return 1\n", level); return 1; } if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL) || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN) ) { syntax(); - debug_printf_exec("run_list_real return 1\n"); + debug_printf_exec("run_list_real lvl %d return 1\n", level); return 1; } } + +#if ENABLE_HUSH_JOB + /* Example of nested list: "while true; do { sleep 1 | exit 2; } done". + * We are saving state before entering outermost list ("while...done") + * so that ctrl-Z will correctly background _entire_ outermost list, + * not just a part of it (like "sleep 1 | exit 2") */ + if (++level == 1 && interactive_fd) { + if (sigsetjmp(toplevel_jb, 1)) { + /* ctrl-Z forked and we are parent; or ctrl-C. + * Sighandler has longjmped us here */ + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + /* Restore level (we can be coming from deep inside + * nested levels) */ + level = 1; +#if ENABLE_FEATURE_SH_STANDALONE + if (nofork_save.saved) { /* if save area is valid */ + debug_printf_jobs("exiting nofork early\n"); + restore_nofork_data(&nofork_save); + } +#endif + if (ctrl_z_flag) { + /* ctrl-Z has forked and stored pid of the child in pi->pid. + * Remember this child as background job */ + insert_bg_job(pi); + } else { + /* ctrl-C. We just stop doing whatever we was doing */ + putchar('\n'); + } + rcode = 0; + goto ret; + } + /* ctrl-Z handler will store pid etc in pi */ + toplevel_list = pi; + ctrl_z_flag = 0; +#if ENABLE_FEATURE_SH_STANDALONE + nofork_save.saved = 0; /* in case we will run a nofork later */ +#endif + signal_SA_RESTART(SIGTSTP, handler_ctrl_z); + signal(SIGINT, handler_ctrl_c); + } +#endif + for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL || pi->r_mode == RES_FOR @@ -1961,7 +1979,7 @@ } } rmode = pi->r_mode; - debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", + debug_printf_exec(": rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode); if (rmode == skip_more_in_this_rmode && flag_skip) { if (pi->followup == PIPE_SEQ) @@ -2044,9 +2062,9 @@ { rcode = checkjobs(pi); } - debug_printf_exec("checkjobs returned %d\n", rcode); + debug_printf_exec(": checkjobs returned %d\n", rcode); } - debug_printf_exec("setting last_return_code=%d\n", rcode); + debug_printf_exec(": setting last_return_code=%d\n", rcode); last_return_code = rcode; pi->num_progs = save_num_progs; /* restore number of programs */ if (rmode == RES_IF || rmode == RES_ELIF) @@ -2062,7 +2080,17 @@ } checkjobs(NULL); } - debug_printf_exec("run_list_real return %d\n", rcode); + +#if ENABLE_HUSH_JOB + if (ctrl_z_flag) { + /* ctrl-Z forked somewhere in the past, we are the child, + * and now we completed running the list. Exit. */ + exit(rcode); + } + ret: + level--; +#endif + debug_printf_exec("run_list_real lvl %d return %d\n", level + 1, rcode); return rcode; } From vda at busybox.net Fri May 4 14:38:19 2007 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 May 2007 14:38:19 -0700 (PDT) Subject: svn commit: trunk/busybox/include Message-ID: <20070504213819.A6FFF48092@busybox.net> Author: vda Date: 2007-05-04 14:38:14 -0700 (Fri, 04 May 2007) New Revision: 18559 Log: fix -Werror compile Modified: trunk/busybox/include/platform.h Changeset: Modified: trunk/busybox/include/platform.h =================================================================== --- trunk/busybox/include/platform.h 2007-05-04 21:37:27 UTC (rev 18558) +++ trunk/busybox/include/platform.h 2007-05-04 21:38:14 UTC (rev 18559) @@ -54,7 +54,11 @@ # define ATTRIBUTE_ALIGNED(m) __attribute__ ((__aligned__(m))) # if __GNUC_PREREQ (3,0) # define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) inline -# define ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) +# if !ENABLE_WERROR +# define ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) +# else +# define ATTRIBUTE_DEPRECATED /* n/a */ +# endif # else # define ATTRIBUTE_ALWAYS_INLINE inline # define ATTRIBUTE_DEPRECATED /* n/a */ From vda at busybox.net Sat May 5 08:10:52 2007 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 May 2007 08:10:52 -0700 (PDT) Subject: svn commit: trunk/busybox/shell Message-ID: <20070505151052.C257E48087@busybox.net> Author: vda Date: 2007-05-05 08:10:52 -0700 (Sat, 05 May 2007) New Revision: 18560 Log: hush: preparatory patch for removing extra empty pipes generation in parse stage. No real code change here. Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2007-05-04 21:38:14 UTC (rev 18559) +++ trunk/busybox/shell/hush.c 2007-05-05 15:10:52 UTC (rev 18560) @@ -125,10 +125,10 @@ #define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0 #endif -#define SPECIAL_VAR_SYMBOL 03 -#define FLAG_EXIT_FROM_LOOP 1 +#define S