diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-26 17:25:33 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-26 17:25:33 +0000 |
| commit | afa7023b465d2abc5a85ecba0917cae974257eaf (patch) | |
| tree | 8c8cc570f93e83a6a38f2b184d83cd7f2fa9985e | |
| parent | 4e1361a4819ad0fcf76e161bfdcdc8bc29c872ff (diff) | |
| download | busybox-w32-afa7023b465d2abc5a85ecba0917cae974257eaf.tar.gz busybox-w32-afa7023b465d2abc5a85ecba0917cae974257eaf.tar.bz2 busybox-w32-afa7023b465d2abc5a85ecba0917cae974257eaf.zip | |
zcip: make it work on NOMMU (+ improve NOMMU support machinery)
fsck: fix bad English in a comment
| -rw-r--r-- | TODO_config_nommu | 6 | ||||
| -rw-r--r-- | e2fsprogs/fsck.c | 7 | ||||
| -rw-r--r-- | include/libbb.h | 7 | ||||
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 9 | ||||
| -rw-r--r-- | libbb/xfuncs.c | 13 | ||||
| -rw-r--r-- | networking/zcip.c | 146 |
6 files changed, 100 insertions, 88 deletions
diff --git a/TODO_config_nommu b/TODO_config_nommu index 74095aa9a..695ac1114 100644 --- a/TODO_config_nommu +++ b/TODO_config_nommu | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | # | 5 | # |
| 6 | # Automatically generated make config: don't edit | 6 | # Automatically generated make config: don't edit |
| 7 | # Busybox version: 1.6.0.svn | 7 | # Busybox version: 1.6.0.svn |
| 8 | # Mon Mar 26 15:00:56 2007 | 8 | # Mon Mar 26 18:36:12 2007 |
| 9 | # | 9 | # |
| 10 | CONFIG_HAVE_DOT_CONFIG=y | 10 | CONFIG_HAVE_DOT_CONFIG=y |
| 11 | 11 | ||
| @@ -266,7 +266,7 @@ CONFIG_RESET=y | |||
| 266 | CONFIG_RESIZE=y | 266 | CONFIG_RESIZE=y |
| 267 | CONFIG_FEATURE_RESIZE_PRINT=y | 267 | CONFIG_FEATURE_RESIZE_PRINT=y |
| 268 | CONFIG_SETCONSOLE=y | 268 | CONFIG_SETCONSOLE=y |
| 269 | # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set | 269 | CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y |
| 270 | CONFIG_SETKEYCODES=y | 270 | CONFIG_SETKEYCODES=y |
| 271 | CONFIG_SETLOGCONS=y | 271 | CONFIG_SETLOGCONS=y |
| 272 | 272 | ||
| @@ -605,7 +605,7 @@ CONFIG_WGET=y | |||
| 605 | CONFIG_FEATURE_WGET_STATUSBAR=y | 605 | CONFIG_FEATURE_WGET_STATUSBAR=y |
| 606 | CONFIG_FEATURE_WGET_AUTHENTICATION=y | 606 | CONFIG_FEATURE_WGET_AUTHENTICATION=y |
| 607 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y | 607 | CONFIG_FEATURE_WGET_LONG_OPTIONS=y |
| 608 | # CONFIG_ZCIP is not set | 608 | CONFIG_ZCIP=y |
| 609 | 609 | ||
| 610 | # | 610 | # |
| 611 | # Process Utilities | 611 | # Process Utilities |
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 447b4d008..b70fd7088 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c | |||
| @@ -509,12 +509,7 @@ static struct fsck_instance *wait_one(int flags) | |||
| 509 | goto ret_inst; | 509 | goto ret_inst; |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | /* | 512 | inst = prev = NULL; /* for gcc */ |
| 513 | * gcc -Wall fails saving throw against stupidity | ||
| 514 | * (inst and prev are thought to be uninitialized variables) | ||
| 515 | */ | ||
| 516 | inst = prev = NULL; | ||
| 517 | |||
| 518 | do { | 513 | do { |
| 519 | pid = waitpid(-1, &status, flags); | 514 | pid = waitpid(-1, &status, flags); |
| 520 | kill_all_if_cancel_requested(); | 515 | kill_all_if_cancel_requested(); |
diff --git a/include/libbb.h b/include/libbb.h index 32e099b54..67fd2af21 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -263,6 +263,13 @@ char *xrealloc_getcwd_or_warn(char *cwd); | |||
| 263 | char *xmalloc_readlink_or_warn(const char *path); | 263 | char *xmalloc_readlink_or_warn(const char *path); |
| 264 | char *xmalloc_realpath(const char *path); | 264 | char *xmalloc_realpath(const char *path); |
| 265 | extern void xstat(const char *filename, struct stat *buf); | 265 | extern void xstat(const char *filename, struct stat *buf); |
| 266 | /* Unlike waitpid, waits ONLY for one process, | ||
| 267 | * It's safe to pass negative 'pids' from failed [v]fork - | ||
| 268 | * wait4pid will return -1 and ECHILD in errno. | ||
| 269 | * IOW: rc = wait4pid(spawn(argv)); | ||
| 270 | * if (rc < 0) bb_perror_msg("%s", argv[0]); | ||
| 271 | * if (rc > 0) bb_error_msg("exit code: %d", rc); | ||
| 272 | */ | ||
| 266 | extern int wait4pid(int pid); | 273 | extern int wait4pid(int pid); |
| 267 | extern void xsetgid(gid_t gid); | 274 | extern void xsetgid(gid_t gid); |
| 268 | extern void xsetuid(uid_t uid); | 275 | extern void xsetuid(uid_t uid); |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 89ae9a73c..ec8b9b1d7 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
| @@ -40,11 +40,14 @@ pid_t spawn(char **argv) | |||
| 40 | * (but don't run atexit() stuff, which would screw up parent.) | 40 | * (but don't run atexit() stuff, which would screw up parent.) |
| 41 | */ | 41 | */ |
| 42 | failed = errno; | 42 | failed = errno; |
| 43 | _exit(0); | 43 | _exit(111); |
| 44 | } | 44 | } |
| 45 | /* parent */ | 45 | /* parent */ |
| 46 | /* Unfortunately, this is not reliable: vfork() | 46 | /* Unfortunately, this is not reliable: according to standards |
| 47 | * can be equivalent to fork() according to standards */ | 47 | * vfork() can be equivalent to fork() and we won't see value |
| 48 | * of 'failed'. | ||
| 49 | * Interested party can wait on pid and learn exit code. | ||
| 50 | * If 111 - then it (most probably) failed to exec */ | ||
| 48 | if (failed) { | 51 | if (failed) { |
| 49 | errno = failed; | 52 | errno = failed; |
| 50 | return -1; | 53 | return -1; |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 14bd62a15..7f870ac8b 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
| @@ -192,9 +192,16 @@ int wait4pid(int pid) | |||
| 192 | { | 192 | { |
| 193 | int status; | 193 | int status; |
| 194 | 194 | ||
| 195 | if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1; | 195 | if (pid <= 0) { |
| 196 | if (WIFEXITED(status)) return WEXITSTATUS(status); | 196 | errno = ECHILD; |
| 197 | if (WIFSIGNALED(status)) return WTERMSIG(status); | 197 | return -1; |
| 198 | } | ||
| 199 | if (waitpid(pid, &status, 0) == -1) | ||
| 200 | return -1; | ||
| 201 | if (WIFEXITED(status)) | ||
| 202 | return WEXITSTATUS(status); | ||
| 203 | if (WIFSIGNALED(status)) | ||
| 204 | return WTERMSIG(status) + 10000; | ||
| 198 | return 0; | 205 | return 0; |
| 199 | } | 206 | } |
| 200 | 207 | ||
diff --git a/networking/zcip.c b/networking/zcip.c index c0cf665dd..6035b91e1 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
| @@ -70,10 +70,6 @@ enum { | |||
| 70 | #define VDBG(fmt,args...) \ | 70 | #define VDBG(fmt,args...) \ |
| 71 | do { } while (0) | 71 | do { } while (0) |
| 72 | 72 | ||
| 73 | static unsigned opts; | ||
| 74 | #define FOREGROUND (opts & 1) | ||
| 75 | #define QUIT (opts & 2) | ||
| 76 | |||
| 77 | /** | 73 | /** |
| 78 | * Pick a random link local IP address on 169.254/16, except that | 74 | * Pick a random link local IP address on 169.254/16, except that |
| 79 | * the first and last 256 addresses are reserved. | 75 | * the first and last 256 addresses are reserved. |
| @@ -128,49 +124,30 @@ static void arp(int fd, struct sockaddr *saddr, int op, | |||
| 128 | } | 124 | } |
| 129 | 125 | ||
| 130 | /** | 126 | /** |
| 131 | * Run a script. | 127 | * Run a script. argv[2] is already NULL. |
| 132 | */ | 128 | */ |
| 133 | static int run(const char *script, const char *arg, const char *intf, struct in_addr *ip) | 129 | static int run(char *argv[3], const char *intf, struct in_addr *ip) |
| 134 | { | 130 | { |
| 135 | int pid, status; | 131 | int status; |
| 136 | const char *why; | ||
| 137 | 132 | ||
| 138 | if(1) { //always true: if (script != NULL) | 133 | VDBG("%s run %s %s\n", intf, argv[0], argv[1]); |
| 139 | VDBG("%s run %s %s\n", intf, script, arg); | ||
| 140 | if (ip != NULL) { | ||
| 141 | char *addr = inet_ntoa(*ip); | ||
| 142 | setenv("ip", addr, 1); | ||
| 143 | bb_info_msg("%s %s %s", arg, intf, addr); | ||
| 144 | } | ||
| 145 | 134 | ||
| 146 | pid = vfork(); | 135 | if (ip) { |
| 147 | if (pid < 0) { // error | 136 | char *addr = inet_ntoa(*ip); |
| 148 | why = "vfork"; | 137 | setenv("ip", addr, 1); |
| 149 | goto bad; | 138 | bb_info_msg("%s %s %s", argv[1], intf, addr); |
| 150 | } else if (pid == 0) { // child | 139 | } |
| 151 | execl(script, script, arg, NULL); | ||
| 152 | bb_perror_msg("execl"); | ||
| 153 | _exit(EXIT_FAILURE); | ||
| 154 | } | ||
| 155 | 140 | ||
| 156 | if (waitpid(pid, &status, 0) <= 0) { | 141 | status = wait4pid(spawn(argv)); |
| 157 | why = "waitpid"; | 142 | if (status < 0) { |
| 158 | goto bad; | 143 | bb_perror_msg("%s %s", argv[1], intf); |
| 159 | } | 144 | return -errno; |
| 160 | if (WEXITSTATUS(status) != 0) { | ||
| 161 | bb_error_msg("script %s failed, exit=%d", | ||
| 162 | script, WEXITSTATUS(status)); | ||
| 163 | return -errno; | ||
| 164 | } | ||
| 165 | } | 145 | } |
| 166 | return 0; | 146 | if (status != 0) |
| 167 | bad: | 147 | bb_error_msg("script %s %s failed, exitcode=%d", argv[0], argv[1], status); |
| 168 | status = -errno; | ||
| 169 | bb_perror_msg("%s %s, %s", arg, intf, why); | ||
| 170 | return status; | 148 | return status; |
| 171 | } | 149 | } |
| 172 | 150 | ||
| 173 | |||
| 174 | /** | 151 | /** |
| 175 | * Return milliseconds of random delay, up to "secs" seconds. | 152 | * Return milliseconds of random delay, up to "secs" seconds. |
| 176 | */ | 153 | */ |
| @@ -182,43 +159,58 @@ static unsigned ATTRIBUTE_ALWAYS_INLINE ms_rdelay(unsigned secs) | |||
| 182 | /** | 159 | /** |
| 183 | * main program | 160 | * main program |
| 184 | */ | 161 | */ |
| 185 | |||
| 186 | /* Used to be auto variables on main() stack, but | ||
| 187 | * most of them were zero-inited. Moving them to bss | ||
| 188 | * is more space-efficient. | ||
| 189 | */ | ||
| 190 | static const struct in_addr null_ip; // = { 0 }; | ||
| 191 | static const struct ether_addr null_addr; // = { {0, 0, 0, 0, 0, 0} }; | ||
| 192 | |||
| 193 | static struct sockaddr saddr; // memset(0); | ||
| 194 | static struct in_addr ip; // = { 0 }; | ||
| 195 | static struct ifreq ifr; //memset(0); | ||
| 196 | |||
| 197 | static char *intf; // = NULL; | ||
| 198 | static char *script; // = NULL; | ||
| 199 | static suseconds_t timeout; // = 0; // milliseconds | ||
| 200 | static unsigned conflicts; // = 0; | ||
| 201 | static unsigned nprobes; // = 0; | ||
| 202 | static unsigned nclaims; // = 0; | ||
| 203 | static int ready; // = 0; | ||
| 204 | static int verbose; // = 0; | ||
| 205 | static int state = PROBE; | ||
| 206 | |||
| 207 | int zcip_main(int argc, char *argv[]); | 162 | int zcip_main(int argc, char *argv[]); |
| 208 | int zcip_main(int argc, char *argv[]) | 163 | int zcip_main(int argc, char *argv[]) |
| 209 | { | 164 | { |
| 165 | int state = PROBE; | ||
| 210 | struct ether_addr eth_addr; | 166 | struct ether_addr eth_addr; |
| 211 | const char *why; | 167 | const char *why; |
| 212 | int fd; | 168 | int fd; |
| 169 | char *r_opt; | ||
| 170 | unsigned opts; | ||
| 171 | |||
| 172 | /* Ugly trick, but I want these zeroed in one go */ | ||
| 173 | struct { | ||
| 174 | const struct in_addr null_ip; | ||
| 175 | const struct ether_addr null_addr; | ||
| 176 | struct sockaddr saddr; | ||
| 177 | struct in_addr ip; | ||
| 178 | struct ifreq ifr; | ||
| 179 | char *intf; | ||
| 180 | char *script_av[3]; | ||
| 181 | suseconds_t timeout; // milliseconds | ||
| 182 | unsigned conflicts; | ||
| 183 | unsigned nprobes; | ||
| 184 | unsigned nclaims; | ||
| 185 | int ready; | ||
| 186 | int verbose; | ||
| 187 | } L; | ||
| 188 | #define null_ip (L.null_ip ) | ||
| 189 | #define null_addr (L.null_addr) | ||
| 190 | #define saddr (L.saddr ) | ||
| 191 | #define ip (L.ip ) | ||
| 192 | #define ifr (L.ifr ) | ||
| 193 | #define intf (L.intf ) | ||
| 194 | #define script_av (L.script_av) | ||
| 195 | #define timeout (L.timeout ) | ||
| 196 | #define conflicts (L.conflicts) | ||
| 197 | #define nprobes (L.nprobes ) | ||
| 198 | #define nclaims (L.nclaims ) | ||
| 199 | #define ready (L.ready ) | ||
| 200 | #define verbose (L.verbose ) | ||
| 201 | |||
| 202 | memset(&L, 0, sizeof(L)); | ||
| 213 | 203 | ||
| 204 | #define FOREGROUND (opts & 1) | ||
| 205 | #define QUIT (opts & 2) | ||
| 214 | // parse commandline: prog [options] ifname script | 206 | // parse commandline: prog [options] ifname script |
| 215 | char *r_opt; | 207 | // exactly 2 args; -v accumulates and implies -f |
| 216 | opt_complementary = "vv:vf"; // -v accumulates and implies -f | 208 | opt_complementary = "=2:vv:vf"; |
| 217 | opts = getopt32(argc, argv, "fqr:v", &r_opt, &verbose); | 209 | opts = getopt32(argc, argv, "fqr:v", &r_opt, &verbose); |
| 218 | if (!FOREGROUND) { | 210 | if (!FOREGROUND) { |
| 219 | /* Do it early, before all bb_xx_msg calls */ | 211 | /* Do it early, before all bb_xx_msg calls */ |
| 220 | logmode = LOGMODE_SYSLOG; | ||
| 221 | openlog(applet_name, 0, LOG_DAEMON); | 212 | openlog(applet_name, 0, LOG_DAEMON); |
| 213 | logmode |= LOGMODE_SYSLOG; | ||
| 222 | } | 214 | } |
| 223 | if (opts & 4) { // -r n.n.n.n | 215 | if (opts & 4) { // -r n.n.n.n |
| 224 | if (inet_aton(r_opt, &ip) == 0 | 216 | if (inet_aton(r_opt, &ip) == 0 |
| @@ -227,16 +219,21 @@ int zcip_main(int argc, char *argv[]) | |||
| 227 | bb_error_msg_and_die("invalid link address"); | 219 | bb_error_msg_and_die("invalid link address"); |
| 228 | } | 220 | } |
| 229 | } | 221 | } |
| 222 | // On NOMMU reexec early (or else we will rerun things twice) | ||
| 223 | #ifdef BB_NOMMU | ||
| 224 | if (!FOREGROUND) | ||
| 225 | bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); | ||
| 226 | #endif | ||
| 230 | argc -= optind; | 227 | argc -= optind; |
| 231 | argv += optind; | 228 | argv += optind; |
| 232 | if (argc != 2) | 229 | |
| 233 | bb_show_usage(); | ||
| 234 | intf = argv[0]; | 230 | intf = argv[0]; |
| 235 | script = argv[1]; | 231 | script_av[0] = argv[1]; |
| 236 | setenv("interface", intf, 1); | 232 | setenv("interface", intf, 1); |
| 237 | 233 | ||
| 238 | // initialize the interface (modprobe, ifup, etc) | 234 | // initialize the interface (modprobe, ifup, etc) |
| 239 | if (run(script, "init", intf, NULL) < 0) | 235 | script_av[1] = (char*)"init"; |
| 236 | if (run(script_av, intf, NULL)) | ||
| 240 | return EXIT_FAILURE; | 237 | return EXIT_FAILURE; |
| 241 | 238 | ||
| 242 | // initialize saddr | 239 | // initialize saddr |
| @@ -271,8 +268,9 @@ int zcip_main(int argc, char *argv[]) | |||
| 271 | 268 | ||
| 272 | // daemonize now; don't delay system startup | 269 | // daemonize now; don't delay system startup |
| 273 | if (!FOREGROUND) { | 270 | if (!FOREGROUND) { |
| 274 | //NOMMU | 271 | #ifndef BB_NOMMU |
| 275 | bb_daemonize(DAEMON_CHDIR_ROOT); | 272 | bb_daemonize(DAEMON_CHDIR_ROOT); |
| 273 | #endif | ||
| 276 | bb_info_msg("start, interface %s", intf); | 274 | bb_info_msg("start, interface %s", intf); |
| 277 | } | 275 | } |
| 278 | 276 | ||
| @@ -375,7 +373,8 @@ int zcip_main(int argc, char *argv[]) | |||
| 375 | state = MONITOR; | 373 | state = MONITOR; |
| 376 | // link is ok to use earlier | 374 | // link is ok to use earlier |
| 377 | // FIXME update filters | 375 | // FIXME update filters |
| 378 | run(script, "config", intf, &ip); | 376 | script_av[1] = (char*)"config"; |
| 377 | run(script_av, intf, &ip); | ||
| 379 | ready = 1; | 378 | ready = 1; |
| 380 | conflicts = 0; | 379 | conflicts = 0; |
| 381 | timeout = -1; // Never timeout in the monitor state. | 380 | timeout = -1; // Never timeout in the monitor state. |
| @@ -429,8 +428,8 @@ int zcip_main(int argc, char *argv[]) | |||
| 429 | // this shouldn't necessarily exit. | 428 | // this shouldn't necessarily exit. |
| 430 | bb_error_msg("%s: poll error", intf); | 429 | bb_error_msg("%s: poll error", intf); |
| 431 | if (ready) { | 430 | if (ready) { |
| 432 | run(script, "deconfig", | 431 | script_av[1] = (char*)"deconfig"; |
| 433 | intf, &ip); | 432 | run(script_av, intf, &ip); |
| 434 | } | 433 | } |
| 435 | return EXIT_FAILURE; | 434 | return EXIT_FAILURE; |
| 436 | } | 435 | } |
| @@ -516,7 +515,8 @@ int zcip_main(int argc, char *argv[]) | |||
| 516 | state = PROBE; | 515 | state = PROBE; |
| 517 | VDBG("defend conflict -- starting over\n"); | 516 | VDBG("defend conflict -- starting over\n"); |
| 518 | ready = 0; | 517 | ready = 0; |
| 519 | run(script, "deconfig", intf, &ip); | 518 | script_av[1] = (char*)"deconfig"; |
| 519 | run(script_av, intf, &ip); | ||
| 520 | 520 | ||
| 521 | // restart the whole protocol | 521 | // restart the whole protocol |
| 522 | pick(&ip); | 522 | pick(&ip); |
| @@ -542,7 +542,7 @@ int zcip_main(int argc, char *argv[]) | |||
| 542 | goto bad; | 542 | goto bad; |
| 543 | } // switch poll | 543 | } // switch poll |
| 544 | } | 544 | } |
| 545 | bad: | 545 | bad: |
| 546 | bb_perror_msg("%s, %s", intf, why); | 546 | bb_perror_msg("%s, %s", intf, why); |
| 547 | return EXIT_FAILURE; | 547 | return EXIT_FAILURE; |
| 548 | } | 548 | } |
