From vda at busybox.net Tue Jul 1 03:00:46 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 03:00:46 -0700 (PDT) Subject: svn commit: trunk/busybox: debianutils include testsuite Message-ID: <20080701100046.F3F2CF8007@busybox.net> Author: vda Date: 2008-07-01 03:00:46 -0700 (Tue, 01 Jul 2008) New Revision: 22580 Log: ssd: do not stat -x EXECUTABLE, it is not needed anymore ssd: use PATH ssd: fix -a without -x case ssd: fix help text ssd: CLOSE_EXTRA_FDS in MMU case too ssd: add testsuite Added: trunk/busybox/testsuite/start-stop-daemon.tests Modified: trunk/busybox/debianutils/start_stop_daemon.c trunk/busybox/include/usage.h Changeset: Modified: trunk/busybox/debianutils/start_stop_daemon.c =================================================================== --- trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 08:51:25 UTC (rev 22579) +++ trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 10:00:46 UTC (rev 22580) @@ -326,7 +326,9 @@ char *signame; char *startas; char *chuid; +#ifdef OLDER_VERSION_OF_X struct stat execstat; +#endif #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY // char *retry_arg = NULL; // int retries = -1; @@ -361,6 +363,8 @@ if (!(opt & OPT_a)) startas = execname; + if (!execname) /* in case -a is given and -x is not */ + execname = startas; // USE_FEATURE_START_STOP_DAEMON_FANCY( // if (retry_arg) @@ -374,7 +378,8 @@ if (errno) user_id = xuname2uid(userspec); } - do_procinit(); /* Both start and stop needs to know current processes */ + /* Both start and stop need to know current processes */ + do_procinit(); if (opt & CTX_STOP) { int i = do_stop(); @@ -383,17 +388,21 @@ if (found) { if (!QUIET) - printf("%s already running\n%d\n", execname, found->pid); + printf("%s is already running\n%u\n", execname, (unsigned)found->pid); return !(opt & OPT_OKNODO); } +#ifdef OLDER_VERSION_OF_X if (execname) xstat(execname, &execstat); +#endif *--argv = startas; if (opt & OPT_BACKGROUND) { #if BB_MMU - bb_daemonize(0); + bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); + /* DAEMON_DEVNULL_STDIO is superfluous - + * it's always done by bb_daemonize() */ #else pid_t pid = vfork(); if (pid < 0) /* error */ @@ -404,19 +413,18 @@ * so "return 0" may do bad things */ _exit(EXIT_SUCCESS); } - /* child */ + /* Child */ setsid(); /* detach from controlling tty */ /* Redirect stdio to /dev/null, close extra FDs. * We do not actually daemonize because of DAEMON_ONLY_SANITIZE */ - bb_daemonize_or_rexec( - DAEMON_DEVNULL_STDIO - + DAEMON_CLOSE_EXTRA_FDS + bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_ONLY_SANITIZE, NULL /* argv, unused */ ); #endif } if (opt & OPT_MAKEPID) { - /* user wants _us_ to make the pidfile */ + /* User wants _us_ to make the pidfile */ write_pidfile(pidfile); } if (opt & OPT_c) { @@ -434,6 +442,6 @@ } } #endif - execv(startas, argv); + execvp(startas, argv); bb_perror_msg_and_die("cannot start %s", startas); } Modified: trunk/busybox/include/usage.h =================================================================== --- trunk/busybox/include/usage.h 2008-07-01 08:51:25 UTC (rev 22579) +++ trunk/busybox/include/usage.h 2008-07-01 10:00:46 UTC (rev 22580) @@ -3638,9 +3638,7 @@ "$ cat TODO | split -a 2 -l 2 TODO_\n" #define start_stop_daemon_trivial_usage \ - "[OPTIONS] [" \ - USE_GETOPT_LONG("--start|--stop") SKIP_GETOPT_LONG("-S|-K") \ - "] ... [-- arguments...]" + "[OPTIONS] [-S|-K] ... [-- arguments...]" #define start_stop_daemon_full_usage "\n\n" \ "Search for matching processes, and then\n" \ "-S: stop all matching processes.\n" \ Added: trunk/busybox/testsuite/start-stop-daemon.tests =================================================================== --- trunk/busybox/testsuite/start-stop-daemon.tests (rev 0) +++ trunk/busybox/testsuite/start-stop-daemon.tests 2008-07-01 10:00:46 UTC (rev 22580) @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright 2008 by Denys Vlasenko +# Licensed under GPL v2, see file LICENSE for details. + +. testing.sh + +# testing "test name" "cmd" "expected result" "file input" "stdin" + +testing "start-stop-daemon -x without -a" \ + 'start-stop-daemon -S -x true 2>&1; echo $?' \ + "0\n" \ + "" "" + +testing "start-stop-daemon -a without -x" \ + 'start-stop-daemon -S -a false 2>&1; echo $?' \ + "1\n" \ + "" "" + +exit $FAILCOUNT Property changes on: trunk/busybox/testsuite/start-stop-daemon.tests ___________________________________________________________________ Name: svn:executable + * From vda at busybox.net Tue Jul 1 03:05:12 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 03:05:12 -0700 (PDT) Subject: svn commit: trunk/busybox/debianutils Message-ID: <20080701100512.93EF53C3F8@busybox.net> Author: vda Date: 2008-07-01 03:05:12 -0700 (Tue, 01 Jul 2008) New Revision: 22581 Log: ssd: fix missed + in prev commit Modified: trunk/busybox/debianutils/start_stop_daemon.c Changeset: Modified: trunk/busybox/debianutils/start_stop_daemon.c =================================================================== --- trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 10:00:46 UTC (rev 22580) +++ trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 10:05:12 UTC (rev 22581) @@ -418,7 +418,7 @@ /* Redirect stdio to /dev/null, close extra FDs. * We do not actually daemonize because of DAEMON_ONLY_SANITIZE */ bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO - DAEMON_CLOSE_EXTRA_FDS + + DAEMON_CLOSE_EXTRA_FDS + DAEMON_ONLY_SANITIZE, NULL /* argv, unused */ ); #endif From vda at busybox.net Tue Jul 1 03:40:41 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 03:40:41 -0700 (PDT) Subject: svn commit: trunk/busybox: archival archival/libunarchive debianuti etc... Message-ID: <20080701104041.F0A7FF800A@busybox.net> Author: vda Date: 2008-07-01 03:40:41 -0700 (Tue, 01 Jul 2008) New Revision: 22582 Log: *: introduce and use xvfork() function old new delta time_main 1052 1285 +233 crontab_main 623 856 +233 ifupdown_main 2202 2403 +201 xvfork - 20 +20 passwd_main 1049 1053 +4 grave 1068 1066 -2 script_main 935 921 -14 vfork_or_die 20 - -20 vfork_compressor 206 175 -31 open_as_user 109 - -109 popen2 218 - -218 edit_file 910 690 -220 run_command 268 - -268 ------------------------------------------------------------------------------ (add/remove: 1/4 grow/shrink: 4/4 up/down: 691/-882) Total: -191 bytes Modified: trunk/busybox/archival/libunarchive/open_transformer.c trunk/busybox/archival/tar.c trunk/busybox/debianutils/start_stop_daemon.c trunk/busybox/include/libbb.h trunk/busybox/libbb/Kbuild trunk/busybox/libbb/vfork_daemon_rexec.c trunk/busybox/miscutils/crontab.c trunk/busybox/miscutils/time.c trunk/busybox/networking/ifupdown.c trunk/busybox/networking/sendmail.c trunk/busybox/shell/hush.c trunk/busybox/util-linux/script.c Changeset: Modified: trunk/busybox/archival/libunarchive/open_transformer.c =================================================================== --- trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -25,9 +25,7 @@ if (pid == -1) bb_perror_msg_and_die("can't fork"); #else - pid = vfork(); - if (pid == -1) - bb_perror_msg_and_die("can't vfork"); + pid = xvfork(); #endif if (pid == 0) { Modified: trunk/busybox/archival/tar.c =================================================================== --- trunk/busybox/archival/tar.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/archival/tar.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -536,9 +536,7 @@ (void) &zip_exec; #endif - gzipPid = vfork(); - if (gzipPid < 0) - bb_perror_msg_and_die("can't vfork"); + gzipPid = xvfork(); if (gzipPid == 0) { /* child */ Modified: trunk/busybox/debianutils/start_stop_daemon.c =================================================================== --- trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -404,9 +404,7 @@ /* DAEMON_DEVNULL_STDIO is superfluous - * it's always done by bb_daemonize() */ #else - pid_t pid = vfork(); - if (pid < 0) /* error */ - bb_perror_msg_and_die("vfork"); + pid_t pid = xvfork(); if (pid != 0) { /* parent */ /* why _exit? the child may have changed the stack, Modified: trunk/busybox/include/libbb.h =================================================================== --- trunk/busybox/include/libbb.h 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/include/libbb.h 2008-07-01 10:40:41 UTC (rev 22582) @@ -719,6 +719,8 @@ #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) #endif +pid_t xvfork(void) FAST_FUNC; + /* NOMMU friendy fork+exec */ pid_t spawn(char **argv) FAST_FUNC; pid_t xspawn(char **argv) FAST_FUNC; Modified: trunk/busybox/libbb/Kbuild =================================================================== --- trunk/busybox/libbb/Kbuild 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/libbb/Kbuild 2008-07-01 10:40:41 UTC (rev 22582) @@ -109,6 +109,7 @@ lib-y += xgetcwd.o lib-y += xgethostbyname.o lib-y += xreadlink.o +lib-y += xvfork.o # conditionally compiled objects: lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o Modified: trunk/busybox/libbb/vfork_daemon_rexec.c =================================================================== --- trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -226,9 +226,7 @@ if (re_execed) return; - pid = vfork(); - if (pid < 0) /* wtf? */ - bb_perror_msg_and_die("vfork"); + pid = xvfork(); if (pid) /* parent */ exit(EXIT_SUCCESS); /* child - re-exec ourself */ Modified: trunk/busybox/miscutils/crontab.c =================================================================== --- trunk/busybox/miscutils/crontab.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/miscutils/crontab.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -38,10 +38,8 @@ static void edit_file(const struct passwd *pas, const char *file) { const char *ptr; - int pid = vfork(); + int pid = xvfork(); - if (pid < 0) /* failure */ - bb_perror_msg_and_die("vfork"); if (pid) { /* parent */ wait4pid(pid); return; @@ -65,9 +63,7 @@ pid_t pid; char c; - pid = vfork(); - if (pid < 0) /* ERROR */ - bb_perror_msg_and_die("vfork"); + pid = xvfork(); if (pid) { /* PARENT */ if (wait4pid(pid) == 0) { /* exitcode 0: child says it can read */ Modified: trunk/busybox/miscutils/time.c =================================================================== --- trunk/busybox/miscutils/time.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/miscutils/time.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -372,9 +372,7 @@ void (*quit_signal)(int); resp->elapsed_ms = monotonic_us() / 1000; - pid = vfork(); /* Run CMD as child process. */ - if (pid < 0) - bb_error_msg_and_die("cannot fork"); + pid = xvfork(); /* Run CMD as child process. */ if (pid == 0) { /* If child. */ /* Don't cast execvp arguments; that causes errors on some systems, versus merely warnings if the cast is left off. */ Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/networking/ifupdown.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -1008,12 +1008,9 @@ xpiped_pair(outfd); fflush(NULL); - pid = vfork(); + pid = xvfork(); - switch (pid) { - case -1: /* failure */ - bb_perror_msg_and_die("vfork"); - case 0: /* child */ + if (pid == 0) { /* child */ /* NB: close _first_, then move fds! */ close(infd.wr); close(outfd.rd); Modified: trunk/busybox/networking/sendmail.c =================================================================== --- trunk/busybox/networking/sendmail.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/networking/sendmail.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -120,15 +120,6 @@ #undef err } -/* libbb candidate */ -static pid_t vfork_or_die(void) -{ - pid_t pid = vfork(); - if (pid < 0) - bb_perror_msg_and_die("vfork"); - return pid; -} - static void launch_helper(const char **argv) { // setup vanilla unidirectional pipes interchange @@ -137,7 +128,7 @@ xpipe(pipes); xpipe(pipes+2); - helper_pid = vfork_or_die(); + helper_pid = xvfork(); idx = (!helper_pid) * 2; xdup2(pipes[idx], STDIN_FILENO); xdup2(pipes[3-idx], STDOUT_FILENO); Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/shell/hush.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -3096,9 +3096,11 @@ * huge=`cat TESTFILE` # will block here forever * echo OK */ - pid = BB_MMU ? fork() : vfork(); + pid = BB_MMU ? fork() : xvfork(); +#if BB_MMU if (pid < 0) - bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork"); + bb_perror_msg_and_die("fork"); +#endif if (pid == 0) { /* child */ if (ENABLE_HUSH_JOB) die_sleep = 0; /* let nofork's xfuncs die */ Modified: trunk/busybox/util-linux/script.c =================================================================== --- trunk/busybox/util-linux/script.c 2008-07-01 10:05:12 UTC (rev 22581) +++ trunk/busybox/util-linux/script.c 2008-07-01 10:40:41 UTC (rev 22582) @@ -87,10 +87,7 @@ /* TODO: SIGWINCH? pass window size changes down to slave? */ - child_pid = vfork(); - if (child_pid < 0) { - bb_perror_msg_and_die("vfork"); - } + child_pid = xvfork(); if (child_pid) { /* parent */ From vda at busybox.net Tue Jul 1 03:55:46 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 03:55:46 -0700 (PDT) Subject: svn commit: trunk/busybox/libbb Message-ID: <20080701105546.731E6F8011@busybox.net> Author: vda Date: 2008-07-01 03:55:45 -0700 (Tue, 01 Jul 2008) New Revision: 22583 Log: add missing file Added: trunk/busybox/libbb/xvfork.c Changeset: Added: trunk/busybox/libbb/xvfork.c =================================================================== --- trunk/busybox/libbb/xvfork.c (rev 0) +++ trunk/busybox/libbb/xvfork.c 2008-07-01 10:55:45 UTC (rev 22583) @@ -0,0 +1,18 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2007 Denys Vlasenko + * + * Licensed under GPL version 2, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +pid_t FAST_FUNC xvfork(void) +{ + pid_t pid = vfork(); + if (pid < 0) + bb_perror_msg_and_die("vfork"); + return pid; +} From vda at busybox.net Tue Jul 1 04:11:24 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 04:11:24 -0700 (PDT) Subject: svn commit: trunk/busybox: archival/libunarchive include libbb netw etc... Message-ID: <20080701111124.CA5E1F8011@busybox.net> Author: vda Date: 2008-07-01 04:11:24 -0700 (Tue, 01 Jul 2008) New Revision: 22584 Log: *: introduce and use xfork() function old new delta xfork - 20 +20 msh_main 1377 1380 +3 mod_process 455 446 -9 forkexit_or_rexec 30 17 -13 expand_variables 1434 1421 -13 open_transformer 91 76 -15 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/4 up/down: 23/-50) Total: -27 bytes Modified: trunk/busybox/archival/libunarchive/open_transformer.c trunk/busybox/include/libbb.h trunk/busybox/libbb/vfork_daemon_rexec.c trunk/busybox/libbb/xvfork.c trunk/busybox/networking/inetd.c trunk/busybox/shell/hush.c trunk/busybox/util-linux/mount.c Changeset: Modified: trunk/busybox/archival/libunarchive/open_transformer.c =================================================================== --- trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -20,14 +20,7 @@ xpiped_pair(fd_pipe); -#if BB_MMU - pid = fork(); - if (pid == -1) - bb_perror_msg_and_die("can't fork"); -#else - pid = xvfork(); -#endif - + pid = BB_MMU ? xfork() : xvfork(); if (pid == 0) { /* child process */ close(fd_pipe.rd); /* We don't want to read from the parent */ Modified: trunk/busybox/include/libbb.h =================================================================== --- trunk/busybox/include/libbb.h 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/include/libbb.h 2008-07-01 11:11:24 UTC (rev 22584) @@ -719,6 +719,9 @@ #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) #endif +#if BB_MMU +pid_t xfork(void) FAST_FUNC; +#endif pid_t xvfork(void) FAST_FUNC; /* NOMMU friendy fork+exec */ Modified: trunk/busybox/libbb/vfork_daemon_rexec.c =================================================================== --- trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -238,9 +238,7 @@ void FAST_FUNC forkexit_or_rexec(void) { pid_t pid; - pid = fork(); - if (pid < 0) /* wtf? */ - bb_perror_msg_and_die("fork"); + pid = xfork(); if (pid) /* parent */ exit(EXIT_SUCCESS); /* child */ Modified: trunk/busybox/libbb/xvfork.c =================================================================== --- trunk/busybox/libbb/xvfork.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/libbb/xvfork.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -16,3 +16,13 @@ bb_perror_msg_and_die("vfork"); return pid; } + +#if BB_MMU +pid_t FAST_FUNC xfork(void) +{ + pid_t pid = fork(); + if (pid < 0) + bb_perror_msg_and_die("vfork" + 1); + return pid; +} +#endif Modified: trunk/busybox/networking/inetd.c =================================================================== --- trunk/busybox/networking/inetd.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/networking/inetd.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -1303,7 +1303,7 @@ pid = vfork(); if (pid < 0) { /* fork error */ - bb_perror_msg("fork"); + bb_perror_msg(BB_MMU ? "vfork" + 1 : "vfork"); sleep(1); restore_sigmask(&omask); maybe_close(accepted_fd); Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/shell/hush.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -1902,7 +1902,7 @@ #endif if (child->pid < 0) { /* [v]fork failed */ /* Clearly indicate, was it fork or vfork */ - bb_perror_msg(BB_MMU ? "fork" : "vfork"); + bb_perror_msg(BB_MMU ? "vfork" + 1 : "vfork"); } else { pi->alive_progs++; #if ENABLE_HUSH_JOB @@ -3096,11 +3096,7 @@ * huge=`cat TESTFILE` # will block here forever * echo OK */ - pid = BB_MMU ? fork() : xvfork(); -#if BB_MMU - if (pid < 0) - bb_perror_msg_and_die("fork"); -#endif + pid = BB_MMU ? xfork() : xvfork(); if (pid == 0) { /* child */ if (ENABLE_HUSH_JOB) die_sleep = 0; /* let nofork's xfuncs die */ Modified: trunk/busybox/util-linux/mount.c =================================================================== --- trunk/busybox/util-linux/mount.c 2008-07-01 10:55:45 UTC (rev 22583) +++ trunk/busybox/util-linux/mount.c 2008-07-01 11:11:24 UTC (rev 22584) @@ -890,6 +890,7 @@ } #if BB_MMU +/* Unlike bb_daemonize(), parent does NOT exit here, but returns 0 */ static int daemonize(void) { int fd; From aldot at busybox.net Tue Jul 1 05:20:21 2008 From: aldot at busybox.net (aldot at busybox.net) Date: Tue, 1 Jul 2008 05:20:21 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080701122021.061E6F8012@busybox.net> Author: aldot Date: 2008-07-01 05:20:20 -0700 (Tue, 01 Jul 2008) New Revision: 22588 Log: - wrap overlong lines Modified: trunk/busybox/miscutils/Config.in Changeset: Modified: trunk/busybox/miscutils/Config.in =================================================================== --- trunk/busybox/miscutils/Config.in 2008-07-01 12:04:28 UTC (rev 22587) +++ trunk/busybox/miscutils/Config.in 2008-07-01 12:20:20 UTC (rev 22588) @@ -167,8 +167,9 @@ default n depends on DEVFSD help - -fg Run the daemon in the foreground. - -np Exit after parsing the configuration file. Do not poll for events. + -fg Run the daemon in the foreground. + -np Exit after parsing the configuration file. + Do not poll for events. config DEVFSD_VERBOSE bool "Increases logging (and size)" @@ -226,7 +227,8 @@ bool "inotifyd" default n help - Simple inotify daemon. Reports filesystem changes. Requires kernel >= 2.6.13 + Simple inotify daemon. Reports filesystem changes. Requires + kernel >= 2.6.13 config LAST bool "last" @@ -503,8 +505,9 @@ default n help A replacement for "stty size". Unlike stty, can report only width, - only height, or both, in any order. It also does not complain on error, - but returns default 80x24. Usage in shell scripts: width=`ttysize w`. + only height, or both, in any order. It also does not complain on + error, but returns default 80x24. + Usage in shell scripts: width=`ttysize w`. config WATCHDOG bool "watchdog" From bugs at busybox.net Tue Jul 1 05:24:31 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Tue, 1 Jul 2008 05:24:31 -0700 Subject: [BusyBox 0003474]: nmeter crashing Message-ID: <38c21e853b24918e611daad160542220@bugs.busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=3474 ====================================================================== Reported By: nuclearcat Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 3474 Category: Other Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 05-28-2008 09:22 PDT Last Modified: 07-01-2008 05:24 PDT ====================================================================== Summary: nmeter crashing Description: While trying to run nmeter on dual opteron machines Proxy-Karam115 ~ # nmeter "CPU %c MEM %[mf] IO %b" Segmentation fault from their dmesg [509567.114845] nmeter[1998]: segfault at 0 ip 08064ef2 sp bfb8f030 error 4 in busybox[8048000+76000] another machine [672036.057858] nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 in busybox[8048000+76000] On another machine defaulthost ~ # nmeter "CPU %c MEM %[mf] IO %b" CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 Segmentation fault [917917.794357] nmeter[27440]: segfault at 0 ip 08064ef2 sp bf84d950 error 4 in busybox[8048000+76000] BusyBox v1.10.1 (2008-04-20 17:31:36 EEST) multi-call binary ====================================================================== ---------------------------------------------------------------------- vda - 05-28-08 11:13 ---------------------------------------------------------------------- I tried to reproduce it with 1.10.2 and it works for me with this .config. Can you confirn that 1.10.2 crashes for you too? Also: nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 Can you look up IP addr 08064ef2 in busybox_unstripped.map? You can find this file in the build directory. Look for like like these: .text.sortcmp 0x000000000808b694 0xac coreutils/lib.a(ls.o) .text.my_stat 0x000000000808b740 0x80 coreutils/lib.a(ls.o) ---------------------------------------------------------------------- nuclearcat - 05-28-08 12:27 ---------------------------------------------------------------------- sunfire-1 busybox-1.10.1 # cat busybox_unstripped.map |grep '08064e' 0x0000000008064e3f 0x5c procps/lib.a(nmeter.o) .text.put 0x0000000008064e9b 0x38 procps/lib.a(nmeter.o) 0x0000000008064ed3 0x2c procps/lib.a(nmeter.o) 0x0000000008064eff 0x9f procps/lib.a(nmeter.o) sunfire-1 busybox-1.10.1 # addr2line -i -e busybox_unstripped 08064ef2 nmeter.c:0 Also few more attempts to find which string fail: Proxy-Karam114 ~ # nmeter "CPU %c MEM %[mf] IO %b" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c" CPU SUUUDDDDii CPU SSUUUUiii. CPU SSUUUUDDii CPU SSUUUUDii. CPU SSUUUUii.. CPU SSUUUUDii. CPU SSUUUUDii. ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b" CPU SUUUUDii.. IO 1.9m 10m CPU SSUUUUDii. IO 5.3m 6.0m ^C Proxy-Karam114 ~ # nmeter "MEM %[mf]" MEM 1.9g MEM 1.9g MEM 1.9g MEM 1.9g MEM 1.9g ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b" CPU SSUUUUDii. IO 2.3m 9.4m ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf] " Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "%c %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "%b %[mf]" 1.4m 288k 1.9g 4.1m 7.9m 1.9g ---------------------------------------------------------------------- vda - 05-30-08 14:55 ---------------------------------------------------------------------- Add a test print in procps/nmeter.c: static void put(const char *s) { int sz = strlen(s); if (sz > outbuf + sizeof(outbuf) - cur_outbuf) sz = outbuf + sizeof(outbuf) - cur_outbuf; bb_error_msg("outbuf %p cur_outbuf %p sz %d", outbuf, cur_outbuf, sz); memcpy(cur_outbuf, s, sz); cur_outbuf += sz; } What does it print in your case? ---------------------------------------------------------------------- nuclearcat - 06-28-08 10:11 ---------------------------------------------------------------------- Sorry for delay, seems last request i didn't receive because of mailserver failure. Issue still actual. Here is debug output: meter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU ii........ IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g ---------------------------------------------------------------------- vda - 06-28-08 15:00 ---------------------------------------------------------------------- nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 .text.put 0x0000000008064e9b 0x38 procps/lib.a(nmeter.o) 0x0000000008064ed3 0x2c procps/lib.a(nmeter.o) 0x0000000008064eff 0x9f procps/lib.a(nmeter.o) From bugs at busybox.net Tue Jul 1 07:24:01 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Tue, 1 Jul 2008 07:24:01 -0700 Subject: [BusyBox 0003474]: nmeter crashing Message-ID: <84e5b1e60686c8cebd9a807c181c4467@busybox.net> The following issue has been CLOSED ====================================================================== http://busybox.net/bugs/view.php?id=3474 ====================================================================== Reported By: nuclearcat Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 3474 Category: Other Reproducibility: always Severity: minor Priority: normal Status: closed Resolution: open Fixed in Version: ====================================================================== Date Submitted: 05-28-2008 09:22 PDT Last Modified: 07-01-2008 07:24 PDT ====================================================================== Summary: nmeter crashing Description: While trying to run nmeter on dual opteron machines Proxy-Karam115 ~ # nmeter "CPU %c MEM %[mf] IO %b" Segmentation fault from their dmesg [509567.114845] nmeter[1998]: segfault at 0 ip 08064ef2 sp bfb8f030 error 4 in busybox[8048000+76000] another machine [672036.057858] nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 in busybox[8048000+76000] On another machine defaulthost ~ # nmeter "CPU %c MEM %[mf] IO %b" CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 CPU .......... MEM 801m IO 0 0 Segmentation fault [917917.794357] nmeter[27440]: segfault at 0 ip 08064ef2 sp bf84d950 error 4 in busybox[8048000+76000] BusyBox v1.10.1 (2008-04-20 17:31:36 EEST) multi-call binary ====================================================================== ---------------------------------------------------------------------- vda - 05-28-08 11:13 ---------------------------------------------------------------------- I tried to reproduce it with 1.10.2 and it works for me with this .config. Can you confirn that 1.10.2 crashes for you too? Also: nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 Can you look up IP addr 08064ef2 in busybox_unstripped.map? You can find this file in the build directory. Look for like like these: .text.sortcmp 0x000000000808b694 0xac coreutils/lib.a(ls.o) .text.my_stat 0x000000000808b740 0x80 coreutils/lib.a(ls.o) ---------------------------------------------------------------------- nuclearcat - 05-28-08 12:27 ---------------------------------------------------------------------- sunfire-1 busybox-1.10.1 # cat busybox_unstripped.map |grep '08064e' 0x0000000008064e3f 0x5c procps/lib.a(nmeter.o) .text.put 0x0000000008064e9b 0x38 procps/lib.a(nmeter.o) 0x0000000008064ed3 0x2c procps/lib.a(nmeter.o) 0x0000000008064eff 0x9f procps/lib.a(nmeter.o) sunfire-1 busybox-1.10.1 # addr2line -i -e busybox_unstripped 08064ef2 nmeter.c:0 Also few more attempts to find which string fail: Proxy-Karam114 ~ # nmeter "CPU %c MEM %[mf] IO %b" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c" CPU SUUUDDDDii CPU SSUUUUiii. CPU SSUUUUDDii CPU SSUUUUDii. CPU SSUUUUii.. CPU SSUUUUDii. CPU SSUUUUDii. ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b" CPU SUUUUDii.. IO 1.9m 10m CPU SSUUUUDii. IO 5.3m 6.0m ^C Proxy-Karam114 ~ # nmeter "MEM %[mf]" MEM 1.9g MEM 1.9g MEM 1.9g MEM 1.9g MEM 1.9g ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b" CPU SSUUUUDii. IO 2.3m 9.4m ^C Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf] " Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b MEM %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c IO %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "CPU %c %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "%c %b %[mf]" Segmentation fault Proxy-Karam114 ~ # nmeter "%b %[mf]" 1.4m 288k 1.9g 4.1m 7.9m 1.9g ---------------------------------------------------------------------- vda - 05-30-08 14:55 ---------------------------------------------------------------------- Add a test print in procps/nmeter.c: static void put(const char *s) { int sz = strlen(s); if (sz > outbuf + sizeof(outbuf) - cur_outbuf) sz = outbuf + sizeof(outbuf) - cur_outbuf; bb_error_msg("outbuf %p cur_outbuf %p sz %d", outbuf, cur_outbuf, sz); memcpy(cur_outbuf, s, sz); cur_outbuf += sz; } What does it print in your case? ---------------------------------------------------------------------- nuclearcat - 06-28-08 10:11 ---------------------------------------------------------------------- Sorry for delay, seems last request i didn't receive because of mailserver failure. Issue still actual. Here is debug output: meter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU ii........ IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf990 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf994 sz 10 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf99e sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a2 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9a7 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9ab sz 5 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b0 sz 4 nmeter: outbuf 0x80bf990 cur_outbuf 0x80bf9b4 sz 1 CPU i......... IO 0 0 MEM 1.9g ---------------------------------------------------------------------- vda - 06-28-08 15:00 ---------------------------------------------------------------------- nmeter[6093]: segfault at 0 ip 08064ef2 sp bffffca0 error 4 .text.put 0x0000000008064e9b 0x38 procps/lib.a(nmeter.o) 0x0000000008064ed3 0x2c procps/lib.a(nmeter.o) 0x0000000008064eff 0x9f procps/lib.a(nmeter.o) From vda at busybox.net Tue Jul 1 08:59:43 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 08:59:43 -0700 (PDT) Subject: svn commit: trunk/busybox: archival archival/libunarchive debianuti etc... Message-ID: <20080701155943.C80353C654@busybox.net> Author: vda Date: 2008-07-01 08:59:42 -0700 (Tue, 01 Jul 2008) New Revision: 22594 Log: revert last two commits. vfork cannot be used in subroutine, it trashes stack on return Removed: trunk/busybox/libbb/xvfork.c Modified: trunk/busybox/archival/libunarchive/open_transformer.c trunk/busybox/archival/tar.c trunk/busybox/debianutils/start_stop_daemon.c trunk/busybox/include/libbb.h trunk/busybox/libbb/Kbuild trunk/busybox/libbb/vfork_daemon_rexec.c trunk/busybox/miscutils/crontab.c trunk/busybox/miscutils/time.c trunk/busybox/networking/ifupdown.c trunk/busybox/networking/inetd.c trunk/busybox/networking/sendmail.c trunk/busybox/shell/hush.c trunk/busybox/util-linux/mount.c trunk/busybox/util-linux/script.c Changeset: Modified: trunk/busybox/archival/libunarchive/open_transformer.c =================================================================== --- trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -20,7 +20,16 @@ xpiped_pair(fd_pipe); - pid = BB_MMU ? xfork() : xvfork(); +#if BB_MMU + pid = fork(); + if (pid == -1) + bb_perror_msg_and_die("can't fork"); +#else + pid = vfork(); + if (pid == -1) + bb_perror_msg_and_die("can't vfork"); +#endif + if (pid == 0) { /* child process */ close(fd_pipe.rd); /* We don't want to read from the parent */ Modified: trunk/busybox/archival/tar.c =================================================================== --- trunk/busybox/archival/tar.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/archival/tar.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -536,7 +536,9 @@ (void) &zip_exec; #endif - gzipPid = xvfork(); + gzipPid = vfork(); + if (gzipPid < 0) + bb_perror_msg_and_die("can't vfork"); if (gzipPid == 0) { /* child */ Modified: trunk/busybox/debianutils/start_stop_daemon.c =================================================================== --- trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/debianutils/start_stop_daemon.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -404,7 +404,9 @@ /* DAEMON_DEVNULL_STDIO is superfluous - * it's always done by bb_daemonize() */ #else - pid_t pid = xvfork(); + pid_t pid = vfork(); + if (pid < 0) /* error */ + bb_perror_msg_and_die("vfork"); if (pid != 0) { /* parent */ /* why _exit? the child may have changed the stack, Modified: trunk/busybox/include/libbb.h =================================================================== --- trunk/busybox/include/libbb.h 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/include/libbb.h 2008-07-01 15:59:42 UTC (rev 22594) @@ -719,11 +719,6 @@ #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) #endif -#if BB_MMU -pid_t xfork(void) FAST_FUNC; -#endif -pid_t xvfork(void) FAST_FUNC; - /* NOMMU friendy fork+exec */ pid_t spawn(char **argv) FAST_FUNC; pid_t xspawn(char **argv) FAST_FUNC; Modified: trunk/busybox/libbb/Kbuild =================================================================== --- trunk/busybox/libbb/Kbuild 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/libbb/Kbuild 2008-07-01 15:59:42 UTC (rev 22594) @@ -109,7 +109,6 @@ lib-y += xgetcwd.o lib-y += xgethostbyname.o lib-y += xreadlink.o -lib-y += xvfork.o # conditionally compiled objects: lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o Modified: trunk/busybox/libbb/vfork_daemon_rexec.c =================================================================== --- trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -226,7 +226,9 @@ if (re_execed) return; - pid = xvfork(); + pid = vfork(); + if (pid < 0) /* wtf? */ + bb_perror_msg_and_die("vfork"); if (pid) /* parent */ exit(EXIT_SUCCESS); /* child - re-exec ourself */ @@ -238,7 +240,9 @@ void FAST_FUNC forkexit_or_rexec(void) { pid_t pid; - pid = xfork(); + pid = fork(); + if (pid < 0) /* wtf? */ + bb_perror_msg_and_die("fork"); if (pid) /* parent */ exit(EXIT_SUCCESS); /* child */ Deleted: trunk/busybox/libbb/xvfork.c =================================================================== --- trunk/busybox/libbb/xvfork.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/libbb/xvfork.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -1,28 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Utility routines. - * - * Copyright (C) 2007 Denys Vlasenko - * - * Licensed under GPL version 2, see file LICENSE in this tarball for details. - */ - -#include "libbb.h" - -pid_t FAST_FUNC xvfork(void) -{ - pid_t pid = vfork(); - if (pid < 0) - bb_perror_msg_and_die("vfork"); - return pid; -} - -#if BB_MMU -pid_t FAST_FUNC xfork(void) -{ - pid_t pid = fork(); - if (pid < 0) - bb_perror_msg_and_die("vfork" + 1); - return pid; -} -#endif Modified: trunk/busybox/miscutils/crontab.c =================================================================== --- trunk/busybox/miscutils/crontab.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/miscutils/crontab.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -38,8 +38,10 @@ static void edit_file(const struct passwd *pas, const char *file) { const char *ptr; - int pid = xvfork(); + int pid = vfork(); + if (pid < 0) /* failure */ + bb_perror_msg_and_die("vfork"); if (pid) { /* parent */ wait4pid(pid); return; @@ -63,7 +65,9 @@ pid_t pid; char c; - pid = xvfork(); + pid = vfork(); + if (pid < 0) /* ERROR */ + bb_perror_msg_and_die("vfork"); if (pid) { /* PARENT */ if (wait4pid(pid) == 0) { /* exitcode 0: child says it can read */ Modified: trunk/busybox/miscutils/time.c =================================================================== --- trunk/busybox/miscutils/time.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/miscutils/time.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -372,7 +372,9 @@ void (*quit_signal)(int); resp->elapsed_ms = monotonic_us() / 1000; - pid = xvfork(); /* Run CMD as child process. */ + pid = vfork(); /* Run CMD as child process. */ + if (pid < 0) + bb_error_msg_and_die("cannot fork"); if (pid == 0) { /* If child. */ /* Don't cast execvp arguments; that causes errors on some systems, versus merely warnings if the cast is left off. */ Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/networking/ifupdown.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -1008,9 +1008,12 @@ xpiped_pair(outfd); fflush(NULL); - pid = xvfork(); + pid = vfork(); - if (pid == 0) { /* child */ + switch (pid) { + case -1: /* failure */ + bb_perror_msg_and_die("vfork"); + case 0: /* child */ /* NB: close _first_, then move fds! */ close(infd.wr); close(outfd.rd); Modified: trunk/busybox/networking/inetd.c =================================================================== --- trunk/busybox/networking/inetd.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/networking/inetd.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -1303,7 +1303,7 @@ pid = vfork(); if (pid < 0) { /* fork error */ - bb_perror_msg(BB_MMU ? "vfork" + 1 : "vfork"); + bb_perror_msg("fork"); sleep(1); restore_sigmask(&omask); maybe_close(accepted_fd); Modified: trunk/busybox/networking/sendmail.c =================================================================== --- trunk/busybox/networking/sendmail.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/networking/sendmail.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -120,6 +120,15 @@ #undef err } +/* libbb candidate */ +static pid_t vfork_or_die(void) +{ + pid_t pid = vfork(); + if (pid < 0) + bb_perror_msg_and_die("vfork"); + return pid; +} + static void launch_helper(const char **argv) { // setup vanilla unidirectional pipes interchange @@ -128,7 +137,7 @@ xpipe(pipes); xpipe(pipes+2); - helper_pid = xvfork(); + helper_pid = vfork_or_die(); idx = (!helper_pid) * 2; xdup2(pipes[idx], STDIN_FILENO); xdup2(pipes[3-idx], STDOUT_FILENO); Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/shell/hush.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -1902,7 +1902,7 @@ #endif if (child->pid < 0) { /* [v]fork failed */ /* Clearly indicate, was it fork or vfork */ - bb_perror_msg(BB_MMU ? "vfork" + 1 : "vfork"); + bb_perror_msg(BB_MMU ? "fork" : "vfork"); } else { pi->alive_progs++; #if ENABLE_HUSH_JOB @@ -3096,7 +3096,9 @@ * huge=`cat TESTFILE` # will block here forever * echo OK */ - pid = BB_MMU ? xfork() : xvfork(); + pid = BB_MMU ? fork() : vfork(); + if (pid < 0) + bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork"); if (pid == 0) { /* child */ if (ENABLE_HUSH_JOB) die_sleep = 0; /* let nofork's xfuncs die */ Modified: trunk/busybox/util-linux/mount.c =================================================================== --- trunk/busybox/util-linux/mount.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/util-linux/mount.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -890,7 +890,6 @@ } #if BB_MMU -/* Unlike bb_daemonize(), parent does NOT exit here, but returns 0 */ static int daemonize(void) { int fd; Modified: trunk/busybox/util-linux/script.c =================================================================== --- trunk/busybox/util-linux/script.c 2008-07-01 14:04:55 UTC (rev 22593) +++ trunk/busybox/util-linux/script.c 2008-07-01 15:59:42 UTC (rev 22594) @@ -87,7 +87,10 @@ /* TODO: SIGWINCH? pass window size changes down to slave? */ - child_pid = xvfork(); + child_pid = vfork(); + if (child_pid < 0) { + bb_perror_msg_and_die("vfork"); + } if (child_pid) { /* parent */ From vda at busybox.net Tue Jul 1 09:09:07 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Jul 2008 09:09:07 -0700 (PDT) Subject: svn commit: trunk/busybox: archival archival/libunarchive miscutils etc... Message-ID: <20080701160907.EB6FF3C654@busybox.net> Author: vda Date: 2008-07-01 09:09:07 -0700 (Tue, 01 Jul 2008) New Revision: 22595 Log: sendmail: fix wrong vfork usage here too *: shorten error texts function old new delta launch_helper - 151 +151 vfork_or_die 20 - -20 sendgetmail_main 1946 1848 -98 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 0/1 up/down: 151/-118) Total: 33 bytes Modified: trunk/busybox/archival/libunarchive/open_transformer.c trunk/busybox/archival/tar.c trunk/busybox/miscutils/time.c trunk/busybox/networking/nc.c trunk/busybox/networking/sendmail.c trunk/busybox/shell/ash.c Changeset: Modified: trunk/busybox/archival/libunarchive/open_transformer.c =================================================================== --- trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/archival/libunarchive/open_transformer.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -23,11 +23,11 @@ #if BB_MMU pid = fork(); if (pid == -1) - bb_perror_msg_and_die("can't fork"); + bb_perror_msg_and_die("vfork" + 1); #else pid = vfork(); if (pid == -1) - bb_perror_msg_and_die("can't vfork"); + bb_perror_msg_and_die("vfork"); #endif if (pid == 0) { Modified: trunk/busybox/archival/tar.c =================================================================== --- trunk/busybox/archival/tar.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/archival/tar.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -538,7 +538,7 @@ gzipPid = vfork(); if (gzipPid < 0) - bb_perror_msg_and_die("can't vfork"); + bb_perror_msg_and_die("vfork"); if (gzipPid == 0) { /* child */ Modified: trunk/busybox/miscutils/time.c =================================================================== --- trunk/busybox/miscutils/time.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/miscutils/time.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -374,7 +374,7 @@ resp->elapsed_ms = monotonic_us() / 1000; pid = vfork(); /* Run CMD as child process. */ if (pid < 0) - bb_error_msg_and_die("cannot fork"); + bb_perror_msg_and_die("fork"); if (pid == 0) { /* If child. */ /* Don't cast execvp arguments; that causes errors on some systems, versus merely warnings if the cast is left off. */ Modified: trunk/busybox/networking/nc.c =================================================================== --- trunk/busybox/networking/nc.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/networking/nc.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -150,12 +150,9 @@ goto accept_again; } /* child (or main thread if no multiple -l) */ - if (cfd) { - dup2(cfd, 0); - close(cfd); - } - dup2(0, 1); - dup2(0, 2); + xmove_fd(cfd, 0); + xdup2(0, 1); + xdup2(0, 2); USE_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) /* Don't print stuff or it will go over the wire.... */ _exit(127); Modified: trunk/busybox/networking/sendmail.c =================================================================== --- trunk/busybox/networking/sendmail.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/networking/sendmail.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -120,15 +120,6 @@ #undef err } -/* libbb candidate */ -static pid_t vfork_or_die(void) -{ - pid_t pid = vfork(); - if (pid < 0) - bb_perror_msg_and_die("vfork"); - return pid; -} - static void launch_helper(const char **argv) { // setup vanilla unidirectional pipes interchange @@ -137,7 +128,9 @@ xpipe(pipes); xpipe(pipes+2); - helper_pid = vfork_or_die(); + helper_pid = vfork(); + if (helper_pid < 0) + bb_perror_msg_and_die("vfork"); idx = (!helper_pid) * 2; xdup2(pipes[idx], STDIN_FILENO); xdup2(pipes[3-idx], STDOUT_FILENO); Modified: trunk/busybox/shell/ash.c =================================================================== --- trunk/busybox/shell/ash.c 2008-07-01 15:59:42 UTC (rev 22594) +++ trunk/busybox/shell/ash.c 2008-07-01 16:09:07 UTC (rev 22595) @@ -4581,7 +4581,7 @@ TRACE(("Fork failed, errno=%d", errno)); if (jp) freejob(jp); - ash_msg_and_raise_error("cannot fork"); + ash_msg_and_raise_error("can't fork"); } if (pid == 0) forkchild(jp, /*n,*/ mode); From solar at busybox.net Tue Jul 1 17:12:07 2008 From: solar at busybox.net (solar at busybox.net) Date: Tue, 1 Jul 2008 17:12:07 -0700 (PDT) Subject: svn commit: trunk/busybox/coreutils Message-ID: <20080702001207.AC8803C6C7@busybox.net> Author: solar Date: 2008-07-01 17:12:06 -0700 (Tue, 01 Jul 2008) New Revision: 22604 Log: - fix trivial exploit vector when setXid Modified: trunk/busybox/coreutils/uname.c Changeset: Modified: trunk/busybox/coreutils/uname.c =================================================================== --- trunk/busybox/coreutils/uname.c 2008-07-01 21:47:24 UTC (rev 22603) +++ trunk/busybox/coreutils/uname.c 2008-07-02 00:12:06 UTC (rev 22604) @@ -89,7 +89,7 @@ delta = utsname_offset; do { if (toprint & 1) { - printf(((char *)(&uname_info)) + *delta); + printf("%s", ((char *)(&uname_info)) + *delta); if (toprint > 1) { bb_putchar(' '); } From vda at busybox.net Wed Jul 2 04:15:00 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Jul 2008 04:15:00 -0700 (PDT) Subject: svn commit: trunk/busybox: applets coreutils editors Message-ID: <20080702111500.926383C5FB@busybox.net> Author: vda Date: 2008-07-02 04:14:59 -0700 (Wed, 02 Jul 2008) New Revision: 22608 Log: uname,individual: fix improper printf usage uname,awk: small code shrink function old new delta uname_main 175 166 -9 nvalloc 167 157 -10 evaluate 6381 6370 -11 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-30) Total: -30 bytes Modified: trunk/busybox/applets/individual.c trunk/busybox/coreutils/uname.c trunk/busybox/editors/awk.c Changeset: Modified: trunk/busybox/applets/individual.c =================================================================== --- trunk/busybox/applets/individual.c 2008-07-02 08:58:18 UTC (rev 22607) +++ trunk/busybox/applets/individual.c 2008-07-02 11:14:59 UTC (rev 22608) @@ -14,13 +14,11 @@ int main(int argc, char **argv) { applet_name = argv[0]; - return APPLET_main(argc,argv); } void bb_show_usage(void) { - printf(APPLET_full_usage "\n"); - + fputs(APPLET_full_usage "\n", stdout); exit(EXIT_FAILURE); } Modified: trunk/busybox/coreutils/uname.c =================================================================== --- trunk/busybox/coreutils/uname.c 2008-07-02 08:58:18 UTC (rev 22607) +++ trunk/busybox/coreutils/uname.c 2008-07-02 11:14:59 UTC (rev 22608) @@ -17,7 +17,7 @@ -m, --machine sun -a, --all SunOS rocky8 4.0 sun - The default behavior is equivalent to `-s'. + The default behavior is equivalent to '-s'. David MacKenzie */ @@ -39,47 +39,43 @@ } uname_info_t; static const char options[] ALIGN1 = "snrvmpa"; -static const unsigned short utsname_offset[] ALIGN2 = { - offsetof(uname_info_t,name.sysname), - offsetof(uname_info_t,name.nodename), - offsetof(uname_info_t,name.release), - offsetof(uname_info_t,name.version), - offsetof(uname_info_t,name.machine), - offsetof(uname_info_t,processor) +static const unsigned short utsname_offset[] = { + offsetof(uname_info_t, name.sysname), + offsetof(uname_info_t, name.nodename), + offsetof(uname_info_t, name.release), + offsetof(uname_info_t, name.version), + offsetof(uname_info_t, name.machine), + offsetof(uname_info_t, processor) }; int uname_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int uname_main(int argc, char **argv) +int uname_main(int argc ATTRIBUTE_UNUSED, char **argv) { uname_info_t uname_info; #if defined(__sparc__) && defined(__linux__) char *fake_sparc = getenv("FAKE_SPARC"); #endif - const unsigned short int *delta; + const unsigned short *delta; char toprint; toprint = getopt32(argv, options); - if (argc != optind) { + if (argv[optind]) { /* coreutils-6.9 compat */ bb_show_usage(); } - if (toprint & (1 << 6)) { + if (toprint & (1 << 6)) { /* -a => all opts on */ toprint = 0x3f; } - if (toprint == 0) { - toprint = 1; /* sysname */ + if (toprint == 0) { /* no opts => -s (sysname) */ + toprint = 1; } - if (uname(&uname_info.name) == -1) { - bb_error_msg_and_die("cannot get system name"); - } + uname(&uname_info.name); /* never fails */ #if defined(__sparc__) && defined(__linux__) - if ((fake_sparc != NULL) - && ((fake_sparc[0] == 'y') - || (fake_sparc[0] == 'Y'))) { + if (fake_sparc && (fake_sparc[0] | 0x20) == 'y') { strcpy(uname_info.name.machine, "sparc"); } #endif @@ -89,7 +85,8 @@ delta = utsname_offset; do { if (toprint & 1) { - printf("%s", ((char *)(&uname_info)) + *delta); + /* printf would not be safe here */ + fputs((char *)(&uname_info) + *delta, stdout); if (toprint > 1) { bb_putchar(' '); } @@ -98,5 +95,5 @@ } while (toprint >>= 1); bb_putchar('\n'); - fflush_stdout_and_exit(EXIT_SUCCESS); + fflush_stdout_and_exit(EXIT_SUCCESS); /* coreutils-6.9 compat */ } Modified: trunk/busybox/editors/awk.c =================================================================== --- trunk/busybox/editors/awk.c 2008-07-02 08:58:18 UTC (rev 22607) +++ trunk/busybox/editors/awk.c 2008-07-02 11:14:59 UTC (rev 22608) @@ -852,11 +852,11 @@ if (!g_cb) { size = (n <= MINNVBLOCK) ? MINNVBLOCK : n; - g_cb = xmalloc(sizeof(nvblock) + size * sizeof(var)); + g_cb = xzalloc(sizeof(nvblock) + size * sizeof(var)); g_cb->size = size; g_cb->pos = g_cb->nv; g_cb->prev = pb; - g_cb->next = NULL; + /*g_cb->next = NULL; - xzalloc did it */ if (pb) pb->next = g_cb; } @@ -2028,9 +2028,9 @@ if (i < 0) i = 0; n = (nargs > 2) ? getvar_i(av[2]) : l-i; if (n < 0) n = 0; - s = xmalloc(n+1); + s = xzalloc(n + 1); strncpy(s, as[0]+i, n); - s[n] = '\0'; + /*s[n] = '\0'; - xzalloc did it */ setvar_p(res, s); break; From vda at busybox.net Wed Jul 2 04:34:50 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Jul 2008 04:34:50 -0700 (PDT) Subject: svn commit: trunk/busybox/docs/busybox.net Message-ID: <20080702113450.30B733C5FB@busybox.net> Author: vda Date: 2008-07-02 04:34:49 -0700 (Wed, 02 Jul 2008) New Revision: 22609 Log: webpage: fix typos Modified: trunk/busybox/docs/busybox.net/news.html Changeset: Modified: trunk/busybox/docs/busybox.net/news.html =================================================================== --- trunk/busybox/docs/busybox.net/news.html 2008-07-02 11:14:59 UTC (rev 22608) +++ trunk/busybox/docs/busybox.net/news.html 2008-07-02 11:34:49 UTC (rev 22609) @@ -24,7 +24,7 @@
  • build system: reinstate CONFIG_CROSS_COMPILE_PREFIX
  • ash: optional bash compatibility features added; other fixes
  • hush: lots and lots of fixes -
  • msh: fix the case where the file has exec bit but can't be run directly (run "$SHELL $file" instead) +
  • msh: fix the case where the file has exec bit but can't be run directly (runs "$SHELL file" instead)
  • msh: fix exit codes when command is not found or can't be execed
  • udhcpc: added workaround for buggy kernels
  • mount: fix mishandling of proto=tcp/udp @@ -36,7 +36,7 @@
  • start-stop-daemon: make --exec follow symlinks (Joakim Tjernlund)
  • date: make it accept ISO date format
  • echo: fix echo -e -n "msg\n\0" (David Pinedo) -
  • httpd: fix several bugs triggered by realtive path in -h DIR +
  • httpd: fix several bugs triggered by relative path in -h DIR
  • printf: fix printf -%s- foo, printf -- -%s- foo
  • syslogd: do not error out on missing files to rotate
  • ls: support Unicode in names From vda at busybox.net Wed Jul 2 15:47:49 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Jul 2008 15:47:49 -0700 (PDT) Subject: svn commit: trunk/busybox/editors Message-ID: <20080702224749.BF96A3C678@busybox.net> Author: vda Date: 2008-07-02 15:47:49 -0700 (Wed, 02 Jul 2008) New Revision: 22613 Log: awk: another smallish code shrink Modified: trunk/busybox/editors/awk.c Changeset: Modified: trunk/busybox/editors/awk.c =================================================================== --- trunk/busybox/editors/awk.c 2008-07-02 16:26:23 UTC (rev 22612) +++ trunk/busybox/editors/awk.c 2008-07-02 22:47:49 UTC (rev 22613) @@ -2028,9 +2028,7 @@ if (i < 0) i = 0; n = (nargs > 2) ? getvar_i(av[2]) : l-i; if (n < 0) n = 0; - s = xzalloc(n + 1); - strncpy(s, as[0]+i, n); - /*s[n] = '\0'; - xzalloc did it */ + s = xstrndup(as[0]+i, n); setvar_p(res, s); break; From vda at busybox.net Fri Jul 4 03:25:45 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Jul 2008 03:25:45 -0700 (PDT) Subject: svn commit: trunk/busybox: include libbb modutils Message-ID: <20080704102546.182AF3C64D@busybox.net> Author: vda Date: 2008-07-04 03:25:44 -0700 (Fri, 04 Jul 2008) New Revision: 22626 Log: modutils: optional modutils-small by Vladimir Dronnikov. 15kb smaller than standard one. libbb/recursive_action.c: commented-out code for aborting the scan. Added: trunk/busybox/modutils/modprobe-small.c Modified: trunk/busybox/include/applets.h trunk/busybox/libbb/recursive_action.c trunk/busybox/modutils/Config.in trunk/busybox/modutils/Kbuild Changeset: Modified: trunk/busybox/include/applets.h =================================================================== --- trunk/busybox/include/applets.h 2008-07-04 09:48:25 UTC (rev 22625) +++ trunk/busybox/include/applets.h 2008-07-04 10:25:44 UTC (rev 22626) @@ -116,6 +116,7 @@ USE_DELGROUP(APPLET_ODDNAME(delgroup, deluser, _BB_DIR_BIN, _BB_SUID_NEVER, delgroup)) USE_DELUSER(APPLET(deluser, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_DEPMOD(APPLET(depmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +USE_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) USE_DEVFSD(APPLET(devfsd, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_DF(APPLET(df, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_APP_DHCPRELAY(APPLET(dhcprelay, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) @@ -188,6 +189,7 @@ USE_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_INOTIFYD(APPLET(inotifyd, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +USE_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) USE_INSTALL(APPLET(install, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) #if ENABLE_FEATURE_IP_ADDRESS \ || ENABLE_FEATURE_IP_ROUTE \ @@ -231,6 +233,7 @@ USE_LS(APPLET_NOEXEC(ls, ls, _BB_DIR_BIN, _BB_SUID_NEVER, ls)) USE_LSATTR(APPLET(lsattr, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +USE_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) USE_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat)) USE_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER)) @@ -249,6 +252,7 @@ USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) +USE_MODPROBE_SMALL(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER))) USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) @@ -293,6 +297,7 @@ USE_RM(APPLET_NOFORK(rm, rm, _BB_DIR_BIN, _BB_SUID_NEVER, rm)) USE_RMDIR(APPLET_NOFORK(rmdir, rmdir, _BB_DIR_BIN, _BB_SUID_NEVER, rmdir)) USE_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +USE_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) USE_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) Modified: trunk/busybox/libbb/recursive_action.c =================================================================== --- trunk/busybox/libbb/recursive_action.c 2008-07-04 09:48:25 UTC (rev 22625) +++ trunk/busybox/libbb/recursive_action.c 2008-07-04 10:25:44 UTC (rev 22626) @@ -111,16 +111,23 @@ } status = TRUE; while ((next = readdir(dir)) != NULL) { + /*int s;*/ char *nextFile; nextFile = concat_subpath_file(fileName, next->d_name); if (nextFile == NULL) continue; /* process every file (NB: ACTION_RECURSE is set in flags) */ - if (!recursive_action(nextFile, flags, fileAction, dirAction, - userData, depth + 1)) - status = FALSE; + /*s =*/ recursive_action(nextFile, flags, fileAction, dirAction, + userData, depth + 1); free(nextFile); +//#define RECURSE_RESULT_ABORT 3 +// if (s == RECURSE_RESULT_ABORT) { +// closedir(dir); +// return s; +// } +// if (s == FALSE) +// status = FALSE; } closedir(dir); Modified: trunk/busybox/modutils/Config.in =================================================================== --- trunk/busybox/modutils/Config.in 2008-07-04 09:48:25 UTC (rev 22625) +++ trunk/busybox/modutils/Config.in 2008-07-04 10:25:44 UTC (rev 22626) @@ -5,14 +5,63 @@ menu "Linux Module Utilities" +config MODPROBE_SMALL + bool "Simplified modutils" + default n + help + Simplified modutils. + + With this option modprobe does not use or require + modules.dep or /etc/modules.conf files. + It scans module files in /lib/modules/`uname -r` and + determines dependencies and module alias names on the fly. + This may make module loading slower, most notably + when one needs to load module by alias (this requires + scanning through module _bodies_). + + Additional module parameters can be stored in + /etc/modules/$module_name files. + + Apart from modprobe, other utilities are also provided: + - insmod is an alias to modprobe + - rmmod is an alias to modprobe -r + - depmod is provided but does nothing + + As of 2008-07, this code is experimental. It it 15kb smaller + than "non-small" modutils. + +config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE + bool "module options on cmdline" + default n + depends on MODPROBE_SMALL + help + Allow insmod and modprobe take module options from command line. + N.B. Very bloaty. + +config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED + bool "Skip loading of already loaded modules" + default n + depends on MODPROBE_SMALL + help + Check if the module is already loaded. + N.B. It's racy. + +config FEATURE_MODPROBE_SMALL_ZIPPED + bool "Handle gzipped or bzipped modules" + default n + depends on MODPROBE_SMALL + help + Handle compressed modules. Bloaty. Sloooow. + config DEPMOD bool "depmod" default n + depends on !MODPROBE_SMALL help depmod generates modules.dep (FIXME: elaborate) config FEATURE_DEPMOD_PRUNE_FANCY - bool "fancy dependency pruning" + bool "Fancy dependency pruning" default n depends on DEPMOD help @@ -26,7 +75,7 @@ If unsure, say N. config FEATURE_DEPMOD_ALIAS - bool "alias support" + bool "Alias support" default n depends on DEPMOD help @@ -38,6 +87,7 @@ config INSMOD bool "insmod" default n + depends on !MODPROBE_SMALL help insmod is used to load specified modules in the running kernel. @@ -93,12 +143,14 @@ config RMMOD bool "rmmod" default n + depends on !MODPROBE_SMALL help rmmod is used to unload specified modules from the kernel. config LSMOD bool "lsmod" default n + depends on !MODPROBE_SMALL help lsmod is used to display a list of loaded modules. @@ -113,6 +165,7 @@ config MODPROBE bool "modprobe" default n + depends on !MODPROBE_SMALL help Handle the loading of modules, and their dependencies on a high level. @@ -196,7 +249,7 @@ # Simulate indentation string "Default directory containing modules" default "/lib/modules" - depends on INSMOD || RMMOD || MODPROBE || DEPMOD + depends on INSMOD || RMMOD || MODPROBE || MODPROBE_SMALL || DEPMOD help Directory that contains kernel modules. Defaults to "/lib/modules" @@ -205,7 +258,7 @@ # Simulate indentation string "Default name of modules.dep" default "modules.dep" - depends on INSMOD || RMMOD || MODPROBE || DEPMOD + depends on INSMOD || RMMOD || MODPROBE || MODPROBE_SMALL || DEPMOD help Filename that contains kernel modules dependencies. Defaults to "modules.dep" Modified: trunk/busybox/modutils/Kbuild =================================================================== --- trunk/busybox/modutils/Kbuild 2008-07-04 09:48:25 UTC (rev 22625) +++ trunk/busybox/modutils/Kbuild 2008-07-04 10:25:44 UTC (rev 22626) @@ -5,8 +5,9 @@ # Licensed under the GPL v2, see the file LICENSE in this tarball. lib-y:= -lib-$(CONFIG_DEPMOD) += depmod.o -lib-$(CONFIG_INSMOD) += insmod.o -lib-$(CONFIG_LSMOD) += lsmod.o -lib-$(CONFIG_MODPROBE) += modprobe.o -lib-$(CONFIG_RMMOD) += rmmod.o +lib-$(CONFIG_DEPMOD) += depmod.o +lib-$(CONFIG_INSMOD) += insmod.o +lib-$(CONFIG_LSMOD) += lsmod.o +lib-$(CONFIG_MODPROBE) += modprobe.o +lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o +lib-$(CONFIG_RMMOD) += rmmod.o Added: trunk/busybox/modutils/modprobe-small.c =================================================================== --- trunk/busybox/modutils/modprobe-small.c (rev 0) +++ trunk/busybox/modutils/modprobe-small.c 2008-07-04 10:25:44 UTC (rev 22626) @@ -0,0 +1,648 @@ +/* vi: set sw=4 ts=4: */ +/* + * simplified modprobe + * + * Copyright (c) 2008 Vladimir Dronnikov + * Copyright (c) 2008 Bernhard Fischer (initial depmod code) + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" +#include "unarchive.h" + +#include /* uname() */ +#include + +/* libbb candidate */ +static void *xmalloc_read(int fd, size_t *sizep) +{ + char *buf; + size_t size, rd_size, total; + off_t to_read; + struct stat st; + + to_read = sizep ? *sizep : INT_MAX; /* max to read */ + + /* Estimate file size */ + st.st_size = 0; /* in case fstat fails, assume 0 */ + fstat(fd, &st); + /* /proc/N/stat files report st_size 0 */ + /* In order to make such files readable, we add small const */ + size = (st.st_size | 0x3ff) + 1; + + total = 0; + buf = NULL; + while (1) { + if (to_read < size) + size = to_read; + buf = xrealloc(buf, total + size + 1); + rd_size = full_read(fd, buf + total, size); + if ((ssize_t)rd_size < 0) { /* error */ + free(buf); + return NULL; + } + total += rd_size; + if (rd_size < size) /* EOF */ + break; + to_read -= rd_size; + if (to_read <= 0) + break; + /* grow by 1/8, but in [1k..64k] bounds */ + size = ((total / 8) | 0x3ff) + 1; + if (size > 64*1024) + size = 64*1024; + } + xrealloc(buf, total + 1); + buf[total] = '\0'; + + if (sizep) + *sizep = total; + return buf; +} + + +//#define dbg1_error_msg(...) ((void)0) +//#define dbg2_error_msg(...) ((void)0) +#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__) +#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__) + +extern int init_module(void *module, unsigned long len, const char *options); +extern int delete_module(const char *module, unsigned flags); +extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret); + +enum { + OPT_q = (1 << 0), /* be quiet */ + OPT_r = (1 << 1), /* module removal instead of loading */ +}; + +typedef struct module_info { + char *pathname; + char *desc; +} module_info; + +/* + * GLOBALS + */ +struct globals { + module_info *modinfo; + char *module_load_options; + int module_count; + int module_found_idx; + int stringbuf_idx; + char stringbuf[32 * 1024]; /* some modules have lots of stuff */ + /* for example, drivers/media/video/saa7134/saa7134.ko */ +}; +#define G (*ptr_to_globals) +#define modinfo (G.modinfo ) +#define module_count (G.module_count ) +#define module_found_idx (G.module_found_idx ) +#define module_load_options (G.module_load_options) +#define stringbuf_idx (G.stringbuf_idx ) +#define stringbuf (G.stringbuf ) +#define INIT_G() do { \ + SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ +} while (0) + + +static void appendc(char c) +{ + if (stringbuf_idx < sizeof(stringbuf)) + stringbuf[stringbuf_idx++] = c; +} + +static void append(const char *s) +{ + size_t len = strlen(s); + if (stringbuf_idx + len < sizeof(stringbuf)) { + memcpy(stringbuf + stringbuf_idx, s, len); + stringbuf_idx += len; + } +} + +static void reset_stringbuf(void) +{ + stringbuf_idx = 0; +} + +static char* copy_stringbuf(void) +{ + char *copy = xmalloc(stringbuf_idx); + return memcpy(copy, stringbuf, stringbuf_idx); +} + +static char* find_keyword(char *ptr, size_t len, const char *word) +{ + int wlen; + + if (!ptr) /* happens if read_module cannot read it */ + return NULL; + + wlen = strlen(word); + len -= wlen - 1; + while ((ssize_t)len > 0) { + char *old = ptr; + /* search for the first char in word */ + ptr = memchr(ptr, *word, len); + if (ptr == NULL) /* no occurance left, done */ + break; + if (strncmp(ptr, word, wlen) == 0) + return ptr + wlen; /* found, return ptr past it */ + ++ptr; + len -= (ptr - old); + } + return NULL; +} + +static void replace(char *s, char what, char with) +{ + while (*s) { + if (what == *s) + *s = with; + ++s; + } +} + +#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED +static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep) +{ + size_t len; + char *image; + char *suffix; + + int fd = open_or_warn(fname, O_RDONLY); + if (fd < 0) + return NULL; + + suffix = strrchr(fname, '.'); + if (suffix) { + if (strcmp(suffix, ".gz") == 0) + fd = open_transformer(fd, unpack_gz_stream, "gunzip"); + else if (strcmp(suffix, ".bz2") == 0) + fd = open_transformer(fd, unpack_bz2_stream, "bunzip2"); + } + + len = (sizep) ? *sizep : 64 * 1024 * 1024; + image = xmalloc_read(fd, &len); + if (!image) + bb_perror_msg("read error from '%s'", fname); + close(fd); + + if (sizep) + *sizep = len; + return image; +} +# define read_module xmalloc_open_zipped_read_close +#else +# define read_module xmalloc_open_read_close +#endif + +/* We use error numbers in a loose translation... */ +static const char *moderror(int err) +{ + switch (err) { + case ENOEXEC: + return "invalid module format"; + case ENOENT: + return "unknown symbol in module or invalid parameter"; + case ESRCH: + return "module has wrong symbol version"; + case EINVAL: /* "invalid parameter" */ + return "unknown symbol in module or invalid parameter" + + sizeof("unknown symbol in module or"); + default: + return strerror(err); + } +} + +static int load_module(const char *fname, const char *options) +{ +#if 1 + int r; + size_t len = MAXINT(ssize_t); + char *module_image; + dbg1_error_msg("load_module('%s','%s')", fname, options); + + module_image = read_module(fname, &len); + r = (!module_image || init_module(module_image, len, options ? options : "") != 0); + free(module_image); + dbg1_error_msg("load_module:%d", r); + return r; /* 0 = success */ +#else + /* For testing */ + dbg1_error_msg("load_module('%s','%s')", fname, options); + return 1; +#endif +} + +static char* parse_module(const char *pathname, const char *name) +{ + char *module_image; + char *ptr; + size_t len; + size_t pos; + dbg1_error_msg("parse_module('%s','%s')", pathname, name); + + /* Read (possibly compressed) module */ + len = 64 * 1024 * 1024; /* 64 Mb at most */ + module_image = read_module(pathname, &len); + + reset_stringbuf(); + + /* First desc line's format is + * "modname alias1 symbol:sym1 alias2 symbol:sym2 " (note trailing ' ') + */ + append(name); + appendc(' '); + /* Aliases */ + pos = 0; + while (1) { + ptr = find_keyword(module_image + pos, len - pos, "alias="); + if (!ptr) { + ptr = find_keyword(module_image + pos, len - pos, "__ksymtab_"); + if (!ptr) + break; + /* DOCME: __ksymtab_gpl and __ksymtab_strings occur + * in many modules. What do they mean? */ + if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) { + dbg2_error_msg("alias: 'symbol:%s'", ptr); + append("symbol:"); + } + } else { + dbg2_error_msg("alias: '%s'", ptr); + } + append(ptr); + appendc(' '); + pos = (ptr - module_image); + } + appendc('\0'); + + /* Second line: "dependency1 depandency2 " (note trailing ' ') */ + ptr = find_keyword(module_image, len, "depends="); + if (ptr && *ptr) { + replace(ptr, ',', ' '); + replace(ptr, '-', '_'); + dbg2_error_msg("dep:'%s'", ptr); + append(ptr); + } + appendc(' '); appendc('\0'); + + free(module_image); + return copy_stringbuf(); +} + +static char* pathname_2_modname(const char *pathname) +{ + const char *fname = bb_get_last_path_component_nostrip(pathname); + const char *suffix = strrstr(fname, ".ko"); + char *name = xstrndup(fname, suffix - fname); + replace(name, '-', '_'); + return name; +} + +static FAST_FUNC int fileAction(const char *pathname, + struct stat *sb ATTRIBUTE_UNUSED, + void *data, + int depth ATTRIBUTE_UNUSED) +{ + int cur; + char *name; + const char *fname; + + pathname += 2; /* skip "./" */ + fname = bb_get_last_path_component_nostrip(pathname); + if (!strrstr(fname, ".ko")) { + dbg1_error_msg("'%s' is not a module", pathname); + return TRUE; /* not a module, continue search */ + } + + cur = module_count++; + if (!(cur & 0xfff)) { + modinfo = xrealloc(modinfo, sizeof(modinfo[0]) * (cur + 0x1001)); + } + modinfo[cur].pathname = xstrdup(pathname); + modinfo[cur].desc = NULL; + modinfo[cur+1].pathname = NULL; + modinfo[cur+1].desc = NULL; + + name = pathname_2_modname(fname); + if (strcmp(name, data) != 0) { + free(name); + dbg1_error_msg("'%s' module name doesn't match", pathname); + return TRUE; /* module name doesn't match, continue search */ + } + + dbg1_error_msg("'%s' module name matches", pathname); + module_found_idx = cur; + modinfo[cur].desc = parse_module(pathname, name); + + if (!(option_mask32 & OPT_r)) { + if (load_module(pathname, module_load_options) == 0) { + /* Load was successful, there is nothing else to do. + * This can happen ONLY for "top-level" module load, + * not a dep, because deps dont do dirscan. */ + exit(EXIT_SUCCESS); + /*free(name);return RECURSE_RESULT_ABORT;*/ + } + } + + free(name); + return TRUE; +} + +static module_info* find_alias(const char *alias) +{ + int i; + dbg1_error_msg("find_alias('%s')", alias); + + /* First try to find by name (cheaper) */ + i = 0; + while (modinfo[i].pathname) { + char *name = pathname_2_modname(modinfo[i].pathname); + if (strcmp(name, alias) == 0) { + dbg1_error_msg("found '%s' in module '%s'", + alias, modinfo[i].pathname); + if (!modinfo[i].desc) + modinfo[i].desc = parse_module(modinfo[i].pathname, name); + free(name); + return &modinfo[i]; + } + free(name); + i++; + } + + /* Scan all module bodies, extract modinfo (it contains aliases) */ + i = 0; + while (modinfo[i].pathname) { + char *desc, *s; + if (!modinfo[i].desc) { + char *name = pathname_2_modname(modinfo[i].pathname); + modinfo[i].desc = parse_module(modinfo[i].pathname, name); + free(name); + } + /* "modname alias1 symbol:sym1 alias2 symbol:sym2 " */ + desc = xstrdup(modinfo[i].desc); + /* Does matching substring exist? */ + replace(desc, ' ', '\0'); + for (s = desc; *s; s += strlen(s) + 1) { + if (strcmp(s, alias) == 0) { + free(desc); + dbg1_error_msg("found alias '%s' in module '%s'", + alias, modinfo[i].pathname); + return &modinfo[i]; + } + } + free(desc); + i++; + } + dbg1_error_msg("find_alias '%s' returns NULL", alias); + return NULL; +} + +#if ENABLE_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED +static int already_loaded(const char *name) +{ + int ret = 0; + int len = strlen(name); + char *line; + FILE* modules; + + modules = xfopen("/proc/modules", "r"); + while ((line = xmalloc_fgets(modules)) != NULL) { + if (strncmp(line, name, len) == 0 && line[len] == ' ') { + free(line); + ret = 1; + break; + } + free(line); + } + fclose(modules); + return ret; +} +#else +#define already_loaded(name) is_rmmod +#endif + +/* + Given modules definition and module name (or alias, or symbol) + load/remove the module respecting dependencies +*/ +#if !ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE +#define process_module(a,b) process_module(a) +#define cmdline_options "" +#endif +static void process_module(char *name, const char *cmdline_options) +{ + char *s, *deps, *options; + module_info *info; + int is_rmmod = (option_mask32 & OPT_r) != 0; + dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); + + replace(name, '-', '_'); + + dbg1_error_msg("already_loaded:%d is_rmmod:%d", already_loaded(name), is_rmmod); + if (already_loaded(name) != is_rmmod) { + dbg1_error_msg("nothing to do for '%s'", name); + return; + } + + options = NULL; + if (!is_rmmod) { + char *opt_filename = xasprintf("/etc/modules/%s", name); + options = xmalloc_open_read_close(opt_filename, NULL); + if (options) + replace(options, '\n', ' '); +#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE + if (cmdline_options) { + /* NB: cmdline_options always have one leading ' ' + * (see main()), we remove it here */ + char *op = xasprintf(options ? "%s %s" : "%s %s" + 3, + cmdline_options + 1, options); + free(options); + options = op; + } +#endif + free(opt_filename); + module_load_options = options; + dbg1_error_msg("process_module('%s'): options:'%s'", name, options); + } + + if (!module_count) { + /* Scan module directory. This is done only once. + * It will attempt module load, and will exit(EXIT_SUCCESS) + * on success. */ + module_found_idx = -1; + recursive_action(".", + ACTION_RECURSE, /* flags */ + fileAction, /* file action */ + NULL, /* dir action */ + name, /* user data */ + 0); /* depth */ + dbg1_error_msg("dirscan complete"); + /* Module was not found, or load failed, or is_rmmod */ + if (module_found_idx >= 0) { /* module was found */ + info = &modinfo[module_found_idx]; + } else { /* search for alias, not a plain module name */ + info = find_alias(name); + } + } else { + info = find_alias(name); + } + + /* rmmod? unload it by name */ + if (is_rmmod) { + if (delete_module(name, O_NONBLOCK|O_EXCL) != 0 + && !(option_mask32 & OPT_q) + ) { + bb_perror_msg("remove '%s'", name); + goto ret; + } + /* N.B. we do not stop here - + * continue to unload modules on which the module depends: + * "-r --remove: option causes modprobe to remove a module. + * If the modules it depends on are also unused, modprobe + * will try to remove them, too." */ + } + + if (!info) { /* both dirscan and find_alias found nothing */ + goto ret; + } + + /* Second line of desc contains dependencies */ + deps = xstrdup(info->desc + strlen(info->desc) + 1); + + /* Transform deps to string list */ + replace(deps, ' ', '\0'); + /* Iterate thru dependencies, trying to (un)load them */ + for (s = deps; *s; s += strlen(s) + 1) { + //if (strcmp(name, s) != 0) // N.B. do loops exist? + dbg1_error_msg("recurse on dep '%s'", s); + process_module(s, NULL); + dbg1_error_msg("recurse on dep '%s' done", s); + } + free(deps); + + /* insmod -> load it */ + if (!is_rmmod) { + errno = 0; + if (load_module(info->pathname, options) != 0) { + if (EEXIST != errno) { + bb_error_msg("insert '%s' %s: %s", + info->pathname, options, + moderror(errno)); + } else { + dbg1_error_msg("insert '%s' %s: %s", + info->pathname, options, + moderror(errno)); + } + } + } + ret: + free(options); +//TODO: return load attempt result from process_module. +//If dep didn't load ok, continuing makes little sense. +} +#undef cmdline_options + + +/* For reference, module-init-tools-0.9.15-pre2 options: + +# insmod +Usage: insmod filename [args] + +# rmmod --help +Usage: rmmod [-fhswvV] modulename ... + -f (or --force) forces a module unload, and may crash your machine. + -s (or --syslog) says use syslog, not stderr + -v (or --verbose) enables more messages + -w (or --wait) begins a module removal even if it is used + and will stop new users from accessing the module (so it + should eventually fall to zero). + +# modprobe +Usage: modprobe [--verbose|--version|--config|--remove] filename [options] + +# depmod --help +depmod 0.9.15-pre2 -- part of module-init-tools +depmod -[aA] [-n -e -v -q -V -r -u] [-b basedirectory] [forced_version] +depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.o module2.o ... +If no arguments (except options) are given, "depmod -a" is assumed + +depmod will output a dependancy list suitable for the modprobe utility. + +Options: + -a, --all Probe all modules + -n, --show Write the dependency file on stdout only + -b basedirectory + --basedir basedirectory Use an image of a module tree. + -F kernelsyms + --filesyms kernelsyms Use the file instead of the + current kernel symbols. +*/ + +int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int modprobe_main(int ATTRIBUTE_UNUSED argc, char **argv) +{ + struct utsname uts; + char applet0 = applet_name[0]; + USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) + + /* depmod is a stub */ + if ('d' == applet0) + return EXIT_SUCCESS; + + /* are we lsmod? -> just dump /proc/modules */ + if ('l' == applet0) { + xprint_and_close_file(xfopen("/proc/modules", "r")); + return EXIT_SUCCESS; + } + + INIT_G(); + + /* insmod, modprobe, rmmod require at least one argument */ + opt_complementary = "-1"; + /* only -q (quiet) and -r (rmmod), + * the rest are accepted and ignored (compat) */ + getopt32(argv, "qrfsvw"); + argv += optind; + + /* are we rmmod? -> simulate modprobe -r */ + if ('r' == applet0) { + option_mask32 |= OPT_r; + } + + /* goto modules directory */ + xchdir(CONFIG_DEFAULT_MODULES_DIR); + uname(&uts); /* never fails */ + xchdir(uts.release); + +#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE + /* If not rmmod, parse possible module options given on command line. + * insmod/modprobe takes one module name, the rest are parameters. */ + options = NULL; + if ('r' != applet0) { + char **arg = argv; + while (*++arg) { + /* Enclose options in quotes */ + char *s = options; + options = xasprintf("%s \"%s\"", s ? s : "", *arg); + free(s); + *arg = NULL; + } + } +#else + if ('r' != applet0) + argv[1] = NULL; +#endif + + /* Load/remove modules. + * Only rmmod loops here, insmod/modprobe has only argv[0] */ + do { + process_module(*argv++, options); + } while (*argv); + + if (ENABLE_FEATURE_CLEAN_UP) { + USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) + } + return EXIT_SUCCESS; +} From vda at busybox.net Fri Jul 4 03:29:30 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Jul 2008 03:29:30 -0700 (PDT) Subject: svn commit: trunk/busybox/libbb Message-ID: <20080704102930.8045A3C64F@busybox.net> Author: vda Date: 2008-07-04 03:29:30 -0700 (Fri, 04 Jul 2008) New Revision: 22627 Log: libbb/recursive_action.c: fix slight error in prev commit Modified: trunk/busybox/libbb/recursive_action.c Changeset: Modified: trunk/busybox/libbb/recursive_action.c =================================================================== --- trunk/busybox/libbb/recursive_action.c 2008-07-04 10:25:44 UTC (rev 22626) +++ trunk/busybox/libbb/recursive_action.c 2008-07-04 10:29:30 UTC (rev 22627) @@ -111,15 +111,17 @@ } status = TRUE; while ((next = readdir(dir)) != NULL) { - /*int s;*/ char *nextFile; nextFile = concat_subpath_file(fileName, next->d_name); if (nextFile == NULL) continue; /* process every file (NB: ACTION_RECURSE is set in flags) */ - /*s =*/ recursive_action(nextFile, flags, fileAction, dirAction, - userData, depth + 1); + if (!recursive_action(nextFile, flags, fileAction, dirAction, + userData, depth + 1)) + status = FALSE; +// s = recursive_action(nextFile, flags, fileAction, dirAction, +// userData, depth + 1); free(nextFile); //#define RECURSE_RESULT_ABORT 3 // if (s == RECURSE_RESULT_ABORT) { From vda at busybox.net Fri Jul 4 14:57:13 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Jul 2008 14:57:13 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080704215713.8666D3C642@busybox.net> Author: vda Date: 2008-07-04 14:57:11 -0700 (Fri, 04 Jul 2008) New Revision: 22636 Log: man: fix missed NULL termination of an array function old new delta man_main 741 721 -20 Modified: trunk/busybox/miscutils/man.c Changeset: Modified: trunk/busybox/miscutils/man.c =================================================================== --- trunk/busybox/miscutils/man.c 2008-07-04 20:35:41 UTC (rev 22635) +++ trunk/busybox/miscutils/man.c 2008-07-04 21:57:11 UTC (rev 22636) @@ -75,7 +75,7 @@ char *sec_list; char *cur_path, *cur_sect; char *line, *value; - int count_mp, alloc_mp, cur_mp; + int count_mp, cur_mp; int opt, not_found; opt_complementary = "-1"; /* at least one argument */ @@ -83,8 +83,8 @@ argv += optind; sec_list = xstrdup("1:2:3:4:5:6:7:8:9"); - alloc_mp = 10; - man_path_list = xmalloc(10 * sizeof(man_path_list[0])); + /* Last valid man_path_list[] is [0x10] */ + man_path_list = xzalloc(0x11 * sizeof(man_path_list[0])); count_mp = 0; man_path_list[0] = xstrdup(getenv("MANPATH")); if (man_path_list[0]) @@ -109,11 +109,13 @@ if (strcmp("MANPATH", line) == 0) { man_path_list[count_mp] = xstrdup(value); count_mp++; - if (alloc_mp == count_mp) { - alloc_mp += 10; - man_path_list = xrealloc(man_path_list, alloc_mp * sizeof(man_path_list[0])); + /* man_path_list is NULL terminated */ + man_path_list[count_mp] = NULL; + if (!(count_mp & 0xf)) { /* 0x10, 0x20 etc */ + /* so that last valid man_path_list[] is [count_mp + 0x10] */ + man_path_list = xrealloc(man_path_list, + (count_mp + 0x11) * sizeof(man_path_list[0])); } - /* thus man_path_list is always NULL terminated */ } if (strcmp("MANSECT", line) == 0) { free(sec_list); From vda at busybox.net Fri Jul 4 14:58:01 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Jul 2008 14:58:01 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080704215802.A6C713C65B@busybox.net> Author: vda Date: 2008-07-04 14:58:00 -0700 (Fri, 04 Jul 2008) New Revision: 22637 Log: man: support cat pages too (by Jason Curl ) function old new delta show_manpage - 112 +112 run_pipe 89 102 +13 man_main 721 725 +4 Modified: trunk/busybox/miscutils/man.c Changeset: Modified: trunk/busybox/miscutils/man.c =================================================================== --- trunk/busybox/miscutils/man.c 2008-07-04 21:57:11 UTC (rev 22636) +++ trunk/busybox/miscutils/man.c 2008-07-04 21:58:00 UTC (rev 22637) @@ -23,7 +23,7 @@ */ -static int run_pipe(const char *unpacker, const char *pager, char *man_filename) +static int run_pipe(const char *unpacker, const char *pager, char *man_filename, int cat) { char *cmd; @@ -35,9 +35,10 @@ return 1; } - /* "2>&1" added so that nroff errors are shown in pager too. + /* "2>&1" is added so that nroff errors are shown in pager too. * Otherwise it may show just empty screen */ - cmd = xasprintf("%s '%s' | gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s", + cmd = xasprintf(cat ? "%s '%s' | %s" + : "%s '%s' | gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s", unpacker, man_filename, pager); system(cmd); free(cmd); @@ -45,22 +46,22 @@ } /* man_filename is of the form "/dir/dir/dir/name.s.bz2" */ -static int show_manpage(const char *pager, char *man_filename) +static int show_manpage(const char *pager, char *man_filename, int cat) { int len; - if (run_pipe("bunzip2 -c", pager, man_filename)) + if (run_pipe("bunzip2 -c", pager, man_filename, cat)) return 1; len = strlen(man_filename) - 1; man_filename[len] = '\0'; /* ".bz2" -> ".gz" */ man_filename[len - 2] = 'g'; - if (run_pipe("gunzip -c", pager, man_filename)) + if (run_pipe("gunzip -c", pager, man_filename, cat)) return 1; man_filename[len - 3] = '\0'; /* ".gz" -> "" */ - if (run_pipe("cat", pager, man_filename)) + if (run_pipe("cat", pager, man_filename, cat)) return 1; return 0; @@ -145,14 +146,30 @@ do { /* for each section */ char *next_sect = strchrnul(cur_sect, ':'); int sect_len = next_sect - cur_sect; + char *man_filename; + int found_here; - char *man_filename = xasprintf("%.*s/man%.*s/%s.%.*s" ".bz2", - path_len, cur_path, - sect_len, cur_sect, - *argv, - sect_len, cur_sect); - found |= show_manpage(pager, man_filename); + /* Search for cat page first */ + man_filename = xasprintf("%.*s/%s%.*s/%s.%.*s" ".bz2", + path_len, cur_path, + "cat", + sect_len, cur_sect, + *argv, + sect_len, cur_sect); + found_here = show_manpage(pager, man_filename, 1); free(man_filename); + if (!found_here) { + man_filename = xasprintf("%.*s/%s%.*s/%s.%.*s" ".bz2", + path_len, cur_path, + "man", + sect_len, cur_sect, + *argv, + sect_len, cur_sect); + found_here = show_manpage(pager, man_filename, 0); + free(man_filename); + } + found |= found_here; + if (found && !(opt & OPT_a)) goto next_arg; cur_sect = next_sect; From vda at busybox.net Sat Jul 5 01:38:42 2008 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 Jul 2008 01:38:42 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080705083842.7A54C3C671@busybox.net> Author: vda Date: 2008-07-05 01:38:41 -0700 (Sat, 05 Jul 2008) New Revision: 22649 Log: man: code shrink function old new delta man_main 725 765 +40 show_manpage 112 - -112 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/0 up/down: 40/-112) Total: -72 bytes Modified: trunk/busybox/miscutils/man.c Changeset: Modified: trunk/busybox/miscutils/man.c =================================================================== --- trunk/busybox/miscutils/man.c 2008-07-05 08:20:34 UTC (rev 22648) +++ trunk/busybox/miscutils/man.c 2008-07-05 08:38:41 UTC (rev 22649) @@ -23,6 +23,10 @@ */ +/* Trick gcc to reuse "cat" string. */ +#define STR_catNULmanNUL "cat\0man" +#define STR_cat "cat\0man" + static int run_pipe(const char *unpacker, const char *pager, char *man_filename, int cat) { char *cmd; @@ -61,7 +65,7 @@ return 1; man_filename[len - 3] = '\0'; /* ".gz" -> "" */ - if (run_pipe("cat", pager, man_filename, cat)) + if (run_pipe(STR_cat, pager, man_filename, cat)) return 1; return 0; @@ -147,28 +151,22 @@ char *next_sect = strchrnul(cur_sect, ':'); int sect_len = next_sect - cur_sect; char *man_filename; - int found_here; + int cat0man1 = 0; - /* Search for cat page first */ - man_filename = xasprintf("%.*s/%s%.*s/%s.%.*s" ".bz2", - path_len, cur_path, - "cat", - sect_len, cur_sect, - *argv, - sect_len, cur_sect); - found_here = show_manpage(pager, man_filename, 1); - free(man_filename); - if (!found_here) { + /* Search for cat, then man page */ + while (cat0man1 < 2) { + int found_here; man_filename = xasprintf("%.*s/%s%.*s/%s.%.*s" ".bz2", - path_len, cur_path, - "man", - sect_len, cur_sect, - *argv, - sect_len, cur_sect); - found_here = show_manpage(pager, man_filename, 0); + path_len, cur_path, + STR_catNULmanNUL + cat0man1 * 4, + sect_len, cur_sect, + *argv, + sect_len, cur_sect); + found_here = show_manpage(pager, man_filename, cat0man1); + found |= found_here; + cat0man1 += found_here + 1; free(man_filename); } - found |= found_here; if (found && !(opt & OPT_a)) goto next_arg; From vda at busybox.net Sat Jul 5 01:50:08 2008 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 Jul 2008 01:50:08 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080705085008.92E893C684@busybox.net> Author: vda Date: 2008-07-05 01:50:08 -0700 (Sat, 05 Jul 2008) New Revision: 22650 Log: man: fix inverted cat/man bool variable Modified: trunk/busybox/miscutils/man.c Changeset: Modified: trunk/busybox/miscutils/man.c =================================================================== --- trunk/busybox/miscutils/man.c 2008-07-05 08:38:41 UTC (rev 22649) +++ trunk/busybox/miscutils/man.c 2008-07-05 08:50:08 UTC (rev 22650) @@ -27,7 +27,7 @@ #define STR_catNULmanNUL "cat\0man" #define STR_cat "cat\0man" -static int run_pipe(const char *unpacker, const char *pager, char *man_filename, int cat) +static int run_pipe(const char *unpacker, const char *pager, char *man_filename, int man) { char *cmd; @@ -41,31 +41,32 @@ /* "2>&1" is added so that nroff errors are shown in pager too. * Otherwise it may show just empty screen */ - cmd = xasprintf(cat ? "%s '%s' | %s" - : "%s '%s' | gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s", - unpacker, man_filename, pager); + cmd = xasprintf( + man ? "%s '%s' | gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s" + : "%s '%s' | %s", + unpacker, man_filename, pager); system(cmd); free(cmd); return 1; } /* man_filename is of the form "/dir/dir/dir/name.s.bz2" */ -static int show_manpage(const char *pager, char *man_filename, int cat) +static int show_manpage(const char *pager, char *man_filename, int man) { int len; - if (run_pipe("bunzip2 -c", pager, man_filename, cat)) + if (run_pipe("bunzip2 -c", pager, man_filename, man)) return 1; len = strlen(man_filename) - 1; man_filename[len] = '\0'; /* ".bz2" -> ".gz" */ man_filename[len - 2] = 'g'; - if (run_pipe("gunzip -c", pager, man_filename, cat)) + if (run_pipe("gunzip -c", pager, man_filename, man)) return 1; man_filename[len - 3] = '\0'; /* ".gz" -> "" */ - if (run_pipe(STR_cat, pager, man_filename, cat)) + if (run_pipe(STR_cat, pager, man_filename, man)) return 1; return 0; From vda at busybox.net Sat Jul 5 02:18:58 2008 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 Jul 2008 02:18:58 -0700 (PDT) Subject: svn commit: trunk/busybox: applets archival archival/bz archival/li etc... Message-ID: <20080705091858.87C323C6C6@busybox.net> Author: vda Date: 2008-07-05 02:18:54 -0700 (Sat, 05 Jul 2008) New Revision: 22651 Log: *: rename ATTRIBUTE_XXX to just XXX. Modified: trunk/busybox/applets/applets.c trunk/busybox/archival/bbunzip.c trunk/busybox/archival/bz/bzlib_private.h trunk/busybox/archival/bzip2.c trunk/busybox/archival/cpio.c trunk/busybox/archival/dpkg.c trunk/busybox/archival/gzip.c trunk/busybox/archival/libunarchive/decompress_unzip.c trunk/busybox/archival/libunarchive/header_skip.c trunk/busybox/archival/tar.c trunk/busybox/archival/unzip.c trunk/busybox/console-tools/clear.c trunk/busybox/console-tools/deallocvt.c trunk/busybox/console-tools/dumpkmap.c trunk/busybox/console-tools/kbd_mode.c trunk/busybox/console-tools/loadfont.c trunk/busybox/console-tools/loadkmap.c trunk/busybox/console-tools/openvt.c trunk/busybox/console-tools/reset.c trunk/busybox/console-tools/resize.c trunk/busybox/console-tools/setconsole.c trunk/busybox/console-tools/setlogcons.c trunk/busybox/coreutils/cat.c trunk/busybox/coreutils/catv.c trunk/busybox/coreutils/chmod.c trunk/busybox/coreutils/chown.c trunk/busybox/coreutils/cksum.c trunk/busybox/coreutils/comm.c trunk/busybox/coreutils/cut.c trunk/busybox/coreutils/date.c trunk/busybox/coreutils/dd.c trunk/busybox/coreutils/du.c trunk/busybox/coreutils/echo.c trunk/busybox/coreutils/env.c trunk/busybox/coreutils/expand.c trunk/busybox/coreutils/false.c trunk/busybox/coreutils/hostid.c trunk/busybox/coreutils/id.c trunk/busybox/coreutils/logname.c trunk/busybox/coreutils/ls.c trunk/busybox/coreutils/md5_sha1_sum.c trunk/busybox/coreutils/mkfifo.c trunk/busybox/coreutils/od_bloaty.c trunk/busybox/coreutils/printenv.c trunk/busybox/coreutils/printf.c trunk/busybox/coreutils/pwd.c trunk/busybox/coreutils/readlink.c trunk/busybox/coreutils/realpath.c trunk/busybox/coreutils/rm.c trunk/busybox/coreutils/rmdir.c trunk/busybox/coreutils/sleep.c trunk/busybox/coreutils/sort.c trunk/busybox/coreutils/split.c trunk/busybox/coreutils/stty.c trunk/busybox/coreutils/sum.c trunk/busybox/coreutils/sync.c trunk/busybox/coreutils/tac.c trunk/busybox/coreutils/test.c trunk/busybox/coreutils/touch.c trunk/busybox/coreutils/tr.c trunk/busybox/coreutils/true.c trunk/busybox/coreutils/tty.c trunk/busybox/coreutils/uname.c trunk/busybox/coreutils/uniq.c trunk/busybox/coreutils/usleep.c trunk/busybox/coreutils/uudecode.c trunk/busybox/coreutils/wc.c trunk/busybox/coreutils/who.c trunk/busybox/coreutils/whoami.c trunk/busybox/debianutils/mktemp.c trunk/busybox/debianutils/pipe_progress.c trunk/busybox/debianutils/run_parts.c trunk/busybox/debianutils/start_stop_daemon.c trunk/busybox/debianutils/which.c trunk/busybox/e2fsprogs/chattr.c trunk/busybox/e2fsprogs/fsck.c trunk/busybox/e2fsprogs/lsattr.c trunk/busybox/e2fsprogs/old_e2fsprogs/ext2fs/getsize.c trunk/busybox/e2fsprogs/old_e2fsprogs/uuid/uuid.h trunk/busybox/editors/awk.c trunk/busybox/editors/cmp.c trunk/busybox/editors/diff.c trunk/busybox/editors/ed.c trunk/busybox/editors/patch.c trunk/busybox/editors/sed.c trunk/busybox/editors/vi.c trunk/busybox/findutils/find.c trunk/busybox/findutils/grep.c trunk/busybox/findutils/xargs.c trunk/busybox/include/libbb.h trunk/busybox/include/platform.h trunk/busybox/init/halt.c trunk/busybox/init/init.c trunk/busybox/libbb/appletlib.c trunk/busybox/libbb/bb_askpass.c trunk/busybox/libbb/messages.c trunk/busybox/libbb/recursive_action.c trunk/busybox/loginutils/addgroup.c trunk/busybox/loginutils/adduser.c trunk/busybox/loginutils/chpasswd.c trunk/busybox/loginutils/cryptpw.c trunk/busybox/loginutils/getty.c trunk/busybox/loginutils/login.c trunk/busybox/loginutils/passwd.c trunk/busybox/loginutils/su.c trunk/busybox/loginutils/sulogin.c trunk/busybox/loginutils/vlock.c trunk/busybox/miscutils/bbconfig.c trunk/busybox/miscutils/chat.c trunk/busybox/miscutils/chrt.c trunk/busybox/miscutils/crond.c trunk/busybox/miscutils/crontab.c trunk/busybox/miscutils/dc.c trunk/busybox/miscutils/devfsd.c trunk/busybox/miscutils/eject.c trunk/busybox/miscutils/fbsplash.c trunk/busybox/miscutils/hdparm.c trunk/busybox/miscutils/inotifyd.c trunk/busybox/miscutils/last.c trunk/busybox/miscutils/last_fancy.c trunk/busybox/miscutils/man.c trunk/busybox/miscutils/microcom.c trunk/busybox/miscutils/mt.c trunk/busybox/miscutils/rx.c trunk/busybox/miscutils/setsid.c trunk/busybox/miscutils/strings.c trunk/busybox/miscutils/taskset.c trunk/busybox/miscutils/time.c trunk/busybox/miscutils/watchdog.c trunk/busybox/modutils/depmod.c trunk/busybox/modutils/insmod.c trunk/busybox/modutils/lsmod.c trunk/busybox/modutils/modprobe-small.c trunk/busybox/networking/arp.c trunk/busybox/networking/arping.c trunk/busybox/networking/brctl.c trunk/busybox/networking/dnsd.c trunk/busybox/networking/ether-wake.c trunk/busybox/networking/ftpgetput.c trunk/busybox/networking/httpd.c trunk/busybox/networking/ifenslave.c trunk/busybox/networking/ifupdown.c trunk/busybox/networking/inetd.c trunk/busybox/networking/interface.c trunk/busybox/networking/ip.c trunk/busybox/networking/isrv_identd.c trunk/busybox/networking/libiproute/ip_common.h trunk/busybox/networking/libiproute/ipaddress.c trunk/busybox/networking/libiproute/iplink.c trunk/busybox/networking/libiproute/iproute.c trunk/busybox/networking/libiproute/iprule.c trunk/busybox/networking/libiproute/ll_map.c trunk/busybox/networking/libiproute/utils.c trunk/busybox/networking/libiproute/utils.h trunk/busybox/networking/nc.c trunk/busybox/networking/nc_bloaty.c trunk/busybox/networking/netstat.c trunk/busybox/networking/ping.c trunk/busybox/networking/pscan.c trunk/busybox/networking/route.c trunk/busybox/networking/sendmail.c trunk/busybox/networking/slattach.c trunk/busybox/networking/tcpudp.c trunk/busybox/networking/telnet.c trunk/busybox/networking/telnetd.c trunk/busybox/networking/tftp.c trunk/busybox/networking/traceroute.c trunk/busybox/networking/udhcp/arpping.c trunk/busybox/networking/udhcp/common.h trunk/busybox/networking/udhcp/dhcpc.c trunk/busybox/networking/udhcp/dhcpd.c trunk/busybox/networking/udhcp/dhcprelay.c trunk/busybox/networking/udhcp/dumpleases.c trunk/busybox/networking/udhcp/files.c trunk/busybox/networking/wget.c trunk/busybox/networking/zcip.c trunk/busybox/printutils/lpd.c trunk/busybox/printutils/lpr.c trunk/busybox/procps/fuser.c trunk/busybox/procps/nmeter.c trunk/busybox/procps/pgrep.c trunk/busybox/procps/pidof.c trunk/busybox/procps/ps.c trunk/busybox/procps/renice.c trunk/busybox/procps/sysctl.c trunk/busybox/procps/top.c trunk/busybox/procps/uptime.c trunk/busybox/procps/watch.c trunk/busybox/runit/chpst.c trunk/busybox/runit/runit_lib.h trunk/busybox/runit/runsv.c trunk/busybox/runit/runsvdir.c trunk/busybox/runit/sv.c trunk/busybox/runit/svlogd.c trunk/busybox/selinux/chcon.c trunk/busybox/selinux/getenforce.c trunk/busybox/selinux/load_policy.c trunk/busybox/selinux/matchpathcon.c trunk/busybox/selinux/runcon.c trunk/busybox/selinux/selinuxenabled.c trunk/busybox/selinux/sestatus.c trunk/busybox/selinux/setfiles.c trunk/busybox/shell/ash.c trunk/busybox/shell/cttyhack.c trunk/busybox/shell/hush.c trunk/busybox/shell/lash_unused.c trunk/busybox/shell/msh.c trunk/busybox/sysklogd/klogd.c trunk/busybox/sysklogd/logread.c trunk/busybox/sysklogd/syslogd.c trunk/busybox/util-linux/dmesg.c trunk/busybox/util-linux/fdformat.c trunk/busybox/util-linux/fdisk.c trunk/busybox/util-linux/fsck_minix.c trunk/busybox/util-linux/hwclock.c trunk/busybox/util-linux/ipcs.c trunk/busybox/util-linux/mdev.c trunk/busybox/util-linux/mkfs_minix.c trunk/busybox/util-linux/more.c trunk/busybox/util-linux/mount.c trunk/busybox/util-linux/rdate.c trunk/busybox/util-linux/readprofile.c trunk/busybox/util-linux/rtcwake.c trunk/busybox/util-linux/script.c trunk/busybox/util-linux/setarch.c trunk/busybox/util-linux/swaponoff.c trunk/busybox/util-linux/switch_root.c trunk/busybox/util-linux/umount.c Changeset: Sorry, the patch is too large to include (5083 lines). Please use ViewCVS to see it! http://busybox.net/cgi-bin/viewcvs.cgi?view=rev&root=svn&rev=22651 From vda at busybox.net Sat Jul 5 10:40:05 2008 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 Jul 2008 10:40:05 -0700 (PDT) Subject: svn commit: trunk/busybox/shell: hush_test/hush-parsing Message-ID: <20080705174005.F2C193C642@busybox.net> Author: vda Date: 2008-07-05 10:40:04 -0700 (Sat, 05 Jul 2008) New Revision: 22655 Log: hush: fix a case where "$@" must expand to no word at all Added: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-05 15:14:11 UTC (rev 22654) +++ trunk/busybox/shell/hush.c 2008-07-05 17:40:04 UTC (rev 22655) @@ -2380,7 +2380,10 @@ p = strchr(p, SPECIAL_VAR_SYMBOL); first_ch = arg[0] | or_mask; /* forced to "quoted" if or_mask = 0x80 */ - ored_ch |= first_ch; + /* "$@" is special. Even if quoted, it can still + * expand to nothing (not even an empty string) */ + if ((first_ch & 0x7f) != '@') + ored_ch |= first_ch; val = NULL; switch (first_ch & 0x7f) { /* Highest bit in first_ch indicates that var is double-quoted */ @@ -2401,6 +2404,7 @@ i = 1; if (!global_argv[i]) break; + ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */ if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ smallint sv = output->o_quote; /* unquoted var's contents should be globbed, so don't quote */ @@ -2932,15 +2936,25 @@ } } #endif - if (word->nonnull /* we saw "xx" or 'xx' */ + if (word->nonnull /* word had "xx" or 'xx' at least as part of it */ /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */ && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL) /* (otherwise it's "abc".... and is already safe) */ ) { - /* Insert "empty variable" reference, this makes - * e.g. "", $empty"" etc to not disappear */ - o_addchr(word, SPECIAL_VAR_SYMBOL); - o_addchr(word, SPECIAL_VAR_SYMBOL); + /* but exclude "$@"! it expands to no word despite "" */ + char *p = word->data; + while (p[0] == SPECIAL_VAR_SYMBOL + && (p[1] & 0x7f) == '@' + && p[2] == SPECIAL_VAR_SYMBOL + ) { + p += 3; + } + if (p == word->data || p[0] != '\0') { + /* Insert "empty variable" reference, this makes + * e.g. "", $empty"" etc to not disappear */ + o_addchr(word, SPECIAL_VAR_SYMBOL); + o_addchr(word, SPECIAL_VAR_SYMBOL); + } } child->argv = add_malloced_string_to_strings(child->argv, xstrdup(word->data)); debug_print_strings("word appended to argv", child->argv); Added: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right =================================================================== --- trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right (rev 0) +++ trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right 2008-07-05 17:40:04 UTC (rev 22655) @@ -0,0 +1,2 @@ +Should be printed +Should be printed Added: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests =================================================================== --- trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests (rev 0) +++ trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests 2008-07-05 17:40:04 UTC (rev 22655) @@ -0,0 +1,14 @@ +if test $# != 0; then + exec "$THIS_SH" "$0" +fi + +# No params! +for a in "$*"; do echo Should be printed; done +for a in "$@"; do echo Should not be printed; done +# Yes, believe it or not, bash is mesmerized by "$@" and stops +# treating "" as "this word cannot be expanded to nothing, +# but must be at least null string". Now it can be expanded to nothing. +for a in "$@"""; do echo Should not be printed; done +for a in """$@"; do echo Should not be printed; done +for a in """$@"''"$@"''; do echo Should not be printed; done +for a in ""; do echo Should be printed; done Property changes on: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests ___________________________________________________________________ Name: svn:executable + * From vda at busybox.net Sat Jul 5 13:30:04 2008 From: vda at busybox.net (vda at busybox.net) Date: Sat, 5 Jul 2008 13:30:04 -0700 (PDT) Subject: svn commit: trunk/busybox/shell: hush_test/hush-misc Message-ID: <20080705203004.84AD73C632@busybox.net> Author: vda Date: 2008-07-05 13:29:59 -0700 (Sat, 05 Jul 2008) New Revision: 22656 Log: hush: support "for v; do ... done" syntax (implied 'in "$@"') Added: trunk/busybox/shell/hush_test/hush-misc/empty_for2.right trunk/busybox/shell/hush_test/hush-misc/empty_for2.tests Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-05 17:40:04 UTC (rev 22655) +++ trunk/busybox/shell/hush.c 2008-07-05 20:29:59 UTC (rev 22656) @@ -508,7 +508,7 @@ /* Debug */ static void syntax_lineno(int line) { - void (*fp)(const char *s, ...); + void FAST_FUNC (*fp)(const char *s, ...); fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die); fp("syntax error hush.c:%d", line); @@ -2026,11 +2026,12 @@ debug_printf_exec("run_list lvl %d return 1\n", run_list_level); return 1; } - if ((rpipe->res_word == RES_IN && rpipe->next->res_word == RES_IN && rpipe->next->progs[0].argv != NULL) - || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN) + if (/* Extra statement after IN: "for a in a b; echo Hi; do ...; done" ? */ + (rpipe->res_word == RES_IN && rpipe->next->res_word == RES_IN && rpipe->next->progs[0].argv != NULL) + /* FOR not followed by IN or DO ("for var; do..." case)? */ + || (rpipe->res_word == RES_FOR && (rpipe->next->res_word != RES_IN && rpipe->next->res_word != RES_DO)) ) { - /* TODO: what is tested in the first condition? */ - syntax("malformed for"); /* 2nd condition: FOR not followed by IN */ + syntax("malformed for"); debug_printf_exec("run_list lvl %d return 1\n", run_list_level); return 1; } @@ -2116,12 +2117,25 @@ if (rword == RES_FOR && pi->num_progs) { if (!for_lcur) { /* first loop through for */ - /* if no variable values after "in" we skip "for" */ - if (!pi->next->progs->argv) - continue; + + static const char encoded_dollar_at[] ALIGN1 = { + SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0' + }; /* encoded representation of "$@" */ + static const char *const encoded_dollar_at_argv[] = { + encoded_dollar_at, NULL + }; /* argv list with one element: "$@" */ + char **vals; + + vals = (char**)encoded_dollar_at_argv; + if (rpipe->next->res_word == RES_IN) { + /* if no variable values after "in" we skip "for" */ + if (!pi->next->progs->argv) + continue; + vals = pi->next->progs->argv; + } /* else: "for var; do..." -> assume "$@" list */ /* create list of variable values */ - debug_print_strings("for_list made from", pi->next->progs->argv); - for_list = expand_strvec_to_strvec(pi->next->progs->argv); + debug_print_strings("for_list made from", vals); + for_list = expand_strvec_to_strvec(vals); debug_print_strings("for_list", for_list); for_lcur = for_list; for_varname = pi->progs->argv[0]; @@ -2707,7 +2721,7 @@ } } -/* the src parameter allows us to peek forward to a possible &n syntax +/* The src parameter allows us to peek forward to a possible &n syntax * for file descriptor duplication, e.g., "2>&1". * Return code is 0 normally, 1 if a syntax error is detected in src. * Resource errors (in xmalloc) cause the process to exit */ @@ -2824,7 +2838,7 @@ { "fi", RES_FI, FLAG_END }, #endif #if ENABLE_HUSH_LOOPS - { "for", RES_FOR, FLAG_IN | FLAG_START }, + { "for", RES_FOR, FLAG_IN | FLAG_DO | FLAG_START }, { "while", RES_WHILE, FLAG_DO | FLAG_START }, { "until", RES_UNTIL, FLAG_DO | FLAG_START }, { "in", RES_IN, FLAG_DO }, @@ -2936,12 +2950,12 @@ } } #endif - if (word->nonnull /* word had "xx" or 'xx' at least as part of it */ + if (word->nonnull /* word had "xx" or 'xx' at least as part of it. */ /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */ && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL) /* (otherwise it's "abc".... and is already safe) */ ) { - /* but exclude "$@"! it expands to no word despite "" */ + /* but exclude "$@" - it expands to no word despite "" */ char *p = word->data; while (p[0] == SPECIAL_VAR_SYMBOL && (p[1] & 0x7f) == '@' Added: trunk/busybox/shell/hush_test/hush-misc/empty_for2.right =================================================================== --- trunk/busybox/shell/hush_test/hush-misc/empty_for2.right (rev 0) +++ trunk/busybox/shell/hush_test/hush-misc/empty_for2.right 2008-07-05 20:29:59 UTC (rev 22656) @@ -0,0 +1,4 @@ +PARAM:abc +PARAM:d e +PARAM:123 +OK: 0 Added: trunk/busybox/shell/hush_test/hush-misc/empty_for2.tests =================================================================== --- trunk/busybox/shell/hush_test/hush-misc/empty_for2.tests (rev 0) +++ trunk/busybox/shell/hush_test/hush-misc/empty_for2.tests 2008-07-05 20:29:59 UTC (rev 22656) @@ -0,0 +1,6 @@ +if test $# = 0; then + exec "$THIS_SH" $0 abc "d e" 123 +fi +false +for v; do echo "PARAM:$v"; done +echo OK: $? Property changes on: trunk/busybox/shell/hush_test/hush-misc/empty_for2.tests ___________________________________________________________________ Name: svn:executable + * From vda at busybox.net Sun Jul 6 00:00:14 2008 From: vda at busybox.net (vda at busybox.net) Date: Sun, 6 Jul 2008 00:00:14 -0700 (PDT) Subject: svn commit: trunk/busybox: init libbb util-linux Message-ID: <20080706070014.DE0013C681@busybox.net> Author: vda Date: 2008-07-06 00:00:11 -0700 (Sun, 06 Jul 2008) New Revision: 22662 Log: mdev: do not follow symlinks in /sys (as was intended prior to rev 18811). If this breaks things, please document why! mdev,init: use shared code for fd sanitization function old new delta bb_daemonize_or_rexec 155 172 +17 mdev_main 500 505 +5 init_main 907 856 -51 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 22/-51) Total: -29 bytes Modified: trunk/busybox/init/init.c trunk/busybox/libbb/vfork_daemon_rexec.c trunk/busybox/util-linux/mdev.c Changeset: Modified: trunk/busybox/init/init.c =================================================================== --- trunk/busybox/init/init.c 2008-07-06 06:27:00 UTC (rev 22661) +++ trunk/busybox/init/init.c 2008-07-06 07:00:11 UTC (rev 22662) @@ -221,20 +221,7 @@ } else { /* Make sure fd 0,1,2 are not closed * (so that they won't be used by future opens) */ - - /* bb_sanitize_stdio(); - WRONG. - * It fails if "/dev/null" doesnt exist, and for init - * this is a real possibility! Open code it instead. */ - - int fd = open(bb_dev_null, O_RDWR); - if (fd < 0) { - /* Give me _ANY_ open descriptor! */ - fd = xopen("/", O_RDONLY); /* we don't believe this can fail */ - } - while ((unsigned)fd < 2) - fd = dup(fd); - if (fd > 2) - close(fd); + bb_sanitize_stdio(); } s = getenv("TERM"); Modified: trunk/busybox/libbb/vfork_daemon_rexec.c =================================================================== --- trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-06 06:27:00 UTC (rev 22661) +++ trunk/busybox/libbb/vfork_daemon_rexec.c 2008-07-06 07:00:11 UTC (rev 22662) @@ -265,7 +265,14 @@ close(2); } - fd = xopen(bb_dev_null, O_RDWR); + fd = open(bb_dev_null, O_RDWR); + if (fd < 0) { + /* NB: we can be called as bb_sanitize_stdio() from init + * or mdev, and there /dev/null may legitimately not (yet) exist! + * Do not use xopen above, but obtain _ANY_ open descriptor, + * even bogus one as below. */ + fd = xopen("/", O_RDONLY); /* don't believe this can fail */ + } while ((unsigned)fd < 2) fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ Modified: trunk/busybox/util-linux/mdev.c =================================================================== --- trunk/busybox/util-linux/mdev.c 2008-07-06 06:27:00 UTC (rev 22661) +++ trunk/busybox/util-linux/mdev.c 2008-07-06 07:00:11 UTC (rev 22662) @@ -19,7 +19,8 @@ #define root_major (G.root_major) #define root_minor (G.root_minor) -#define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ +/* Prevent infinite loops in /sys symlinks */ +#define MAX_SYSFS_DEPTH 3 /* We use additional 64+ bytes in make_device() */ #define SCRATCH_SIZE 80 @@ -392,11 +393,17 @@ char *env_path; RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); -#ifdef YOU_WANT_TO_DEBUG_HOTPLUG_EVENTS + /* We can be called as hotplug helper */ /* Kernel cannot provide suitable stdio fds for us, do it ourself */ +#if 1 + bb_sanitize_stdio(); +#else + /* Debug code */ /* Replace LOGFILE by other file or device name if you need */ #define LOGFILE "/dev/console" - xmove_fd(xopen("/dev/null", O_RDONLY), STDIN_FILENO); + /* Just making sure fd 0 is not closed, + * we don't really intend to read from it */ + xmove_fd(xopen("/", O_RDONLY), STDIN_FILENO); xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDOUT_FILENO); xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDERR_FILENO); #endif @@ -414,11 +421,11 @@ root_minor = minor(st.st_dev); recursive_action("/sys/block", - ACTION_RECURSE | ACTION_FOLLOWLINKS, + ACTION_RECURSE /* no ACTION_FOLLOWLINKS! */, fileAction, dirAction, temp, 0); recursive_action("/sys/class", - ACTION_RECURSE | ACTION_FOLLOWLINKS, + ACTION_RECURSE /* no ACTION_FOLLOWLINKS! */, fileAction, dirAction, temp, 0); } else { From vda at busybox.net Sun Jul 6 03:01:13 2008 From: vda at busybox.net (vda at busybox.net) Date: Sun, 6 Jul 2008 03:01:13 -0700 (PDT) Subject: svn commit: trunk/busybox/shell: hush_test/hush-misc Message-ID: <20080706100113.AFDFE3C6A7@busybox.net> Author: vda Date: 2008-07-06 03:01:13 -0700 (Sun, 06 Jul 2008) New Revision: 22664 Log: hush: support "for if in do done then; do echo $if; done" case function old new delta done_pipe 83 95 +12 parse_stream 1758 1764 +6 done_word 674 647 -27 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 18/-27) Total: -9 bytes Added: trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.right trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.tests Modified: trunk/busybox/shell/hush.c Changeset: Modified: trunk/busybox/shell/hush.c =================================================================== --- trunk/busybox/shell/hush.c 2008-07-06 07:34:41 UTC (rev 22663) +++ trunk/busybox/shell/hush.c 2008-07-06 10:01:13 UTC (rev 22664) @@ -1344,7 +1344,7 @@ if (redir->dup == -1) { char *p; mode = redir_table[redir->rd_type].mode; -//TODO: check redir to names like '\\' +//TODO: check redir for names like '\\' p = expand_string_to_string(redir->rd_filename); openfd = open_or_warn(p, mode); free(p); @@ -2854,17 +2854,7 @@ continue; debug_printf("found reserved word %s, res %d\n", r->literal, r->res); if (r->flag == 0) { /* '!' */ -#if ENABLE_HUSH_LOOPS - if (ctx->ctx_res_w == RES_IN) { - /* 'for a in ! a b c; ...' - ! isn't a keyword here */ - break; - } -#endif - if (ctx->ctx_inverted /* bash doesn't accept '! ! true' */ -#if ENABLE_HUSH_LOOPS - || ctx->ctx_res_w == RES_FOR /* example: 'for ! a' */ -#endif - ) { + if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */ syntax(NULL); IF_HAS_KEYWORDS(ctx->ctx_res_w = RES_SNTX;) } @@ -2885,7 +2875,7 @@ *new = *ctx; /* physical copy */ initialize_context(ctx); ctx->stack = new; - } else if (ctx->ctx_res_w == RES_NONE || !(ctx->old_flag & (1 << r->res))) { + } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) { syntax(NULL); ctx->ctx_res_w = RES_SNTX; return 1; @@ -2940,7 +2930,10 @@ return 1; } #if HAS_KEYWORDS - if (!child->argv) { /* if it's the first word... */ + if (!child->argv /* if it's the first word... */ + && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */ + && ctx->ctx_res_w != RES_IN + ) { debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); if (reserved_word(word, ctx)) { o_reset(word); @@ -2953,9 +2946,9 @@ if (word->nonnull /* word had "xx" or 'xx' at least as part of it. */ /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */ && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL) - /* (otherwise it's "abc".... and is already safe) */ + /* (otherwise it's known to be not empty and is already safe) */ ) { - /* but exclude "$@" - it expands to no word despite "" */ + /* exclude "$@" - it can expand to no word despite "" */ char *p = word->data; while (p[0] == SPECIAL_VAR_SYMBOL && (p[1] & 0x7f) == '@' @@ -2964,7 +2957,9 @@ p += 3; } if (p == word->data || p[0] != '\0') { - /* Insert "empty variable" reference, this makes + /* saw no "$@", or not only "$@" but some + * real text is there too */ + /* insert "empty variable" reference, this makes * e.g. "", $empty"" etc to not disappear */ o_addchr(word, SPECIAL_VAR_SYMBOL); o_addchr(word, SPECIAL_VAR_SYMBOL); @@ -2979,8 +2974,13 @@ #if ENABLE_HUSH_LOOPS /* Force FOR to have just one word (variable name) */ - if (ctx->ctx_res_w == RES_FOR) + /* NB: basically, this makes hush see "for v in ..." syntax as if + * as it is "for v; in ...". FOR and IN become two pipe structs + * in parse tree. */ + if (ctx->ctx_res_w == RES_FOR) { +//TODO: check that child->argv[0] is a valid variable name! done_pipe(ctx, PIPE_SEQ); + } #endif debug_printf_parse("done_word return 0\n"); return 0; @@ -3030,19 +3030,28 @@ debug_printf_parse("done_pipe entered, followup %d\n", type); not_null = done_command(ctx); /* implicit closure of previous command */ ctx->pipe->followup = type; - IF_HAS_KEYWORDS(ctx->pipe->res_word = ctx->ctx_res_w;) IF_HAS_KEYWORDS(ctx->pipe->pi_inverted = ctx->ctx_inverted;) IF_HAS_KEYWORDS(ctx->ctx_inverted = 0;) + IF_HAS_KEYWORDS(ctx->pipe->res_word = ctx->ctx_res_w;) /* Without this check, even just on command line generates * tree of three NOPs (!). Which is harmless but annoying. * IOW: it is safe to do it unconditionally. - * RES_IN case is for "for a in; do ..." (empty IN set) - * to work. */ - if (not_null USE_HUSH_LOOPS(|| ctx->pipe->res_word == RES_IN)) { + * RES_NONE case is for "for a in; do ..." (empty IN set) + * to work, possibly other cases too. */ + if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) { struct pipe *new_p = new_pipe(); ctx->pipe->next = new_p; ctx->pipe = new_p; ctx->child = NULL; /* needed! */ + /* RES_IF, RES_WHILE etc are "sticky" - + * they remain set for commands inside if/while. + * This is used to control execution. + * RES_FOR and RES_IN are NOT sticky (needed to support + * cases where variable or value happens to match a keyword): + */ + if (ctx->ctx_res_w == RES_FOR + || ctx->ctx_res_w == RES_IN) + ctx->ctx_res_w = RES_NONE; /* Create the memory for child, roughly: * ctx->pipe->progs = new struct child_prog; * ctx->pipe->progs[0].family = ctx->pipe; @@ -3444,7 +3453,7 @@ return 0; } -/* Scan input, call done_word() whenever full IFS delemited word was seen. +/* Scan input, call done_word() whenever full IFS delimited word was seen. * call done_pipe if '\n' was seen (and end_trigger != NULL) * Return if (non-quoted) char in end_trigger was seen; or on parse error. */ /* Return code is 0 if end_trigger char is met, @@ -3517,7 +3526,9 @@ //err chk? done_pipe(ctx, PIPE_SEQ); } - if (!HAS_KEYWORDS IF_HAS_KEYWORDS(|| ctx->ctx_res_w == RES_NONE)) { + if (!HAS_KEYWORDS + IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0)) + ) { debug_printf_parse("parse_stream return 0: end_trigger char found\n"); return 0; } Added: trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.right =================================================================== --- trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.right (rev 0) +++ trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.right 2008-07-06 10:01:13 UTC (rev 22664) @@ -0,0 +1,4 @@ +do +done +then +OK: 0 Added: trunk/busybox/shell/hush_test/hush-misc/for_with_keywords.tests =================================================================== --- tr