aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-26 17:25:33 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-26 17:25:33 +0000
commitfe8d1db385d1de65c0f28db4c0ee7a430b0b959f (patch)
tree8c8cc570f93e83a6a38f2b184d83cd7f2fa9985e
parenta30c46a71aad82df94777af890e8f252b4b344ab (diff)
downloadbusybox-w32-fe8d1db385d1de65c0f28db4c0ee7a430b0b959f.tar.gz
busybox-w32-fe8d1db385d1de65c0f28db4c0ee7a430b0b959f.tar.bz2
busybox-w32-fe8d1db385d1de65c0f28db4c0ee7a430b0b959f.zip
zcip: make it work on NOMMU (+ improve NOMMU support machinery)
fsck: fix bad English in a comment git-svn-id: svn://busybox.net/trunk/busybox@18248 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--TODO_config_nommu6
-rw-r--r--e2fsprogs/fsck.c7
-rw-r--r--include/libbb.h7
-rw-r--r--libbb/vfork_daemon_rexec.c9
-rw-r--r--libbb/xfuncs.c13
-rw-r--r--networking/zcip.c146
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#
10CONFIG_HAVE_DOT_CONFIG=y 10CONFIG_HAVE_DOT_CONFIG=y
11 11
@@ -266,7 +266,7 @@ CONFIG_RESET=y
266CONFIG_RESIZE=y 266CONFIG_RESIZE=y
267CONFIG_FEATURE_RESIZE_PRINT=y 267CONFIG_FEATURE_RESIZE_PRINT=y
268CONFIG_SETCONSOLE=y 268CONFIG_SETCONSOLE=y
269# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set 269CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y
270CONFIG_SETKEYCODES=y 270CONFIG_SETKEYCODES=y
271CONFIG_SETLOGCONS=y 271CONFIG_SETLOGCONS=y
272 272
@@ -605,7 +605,7 @@ CONFIG_WGET=y
605CONFIG_FEATURE_WGET_STATUSBAR=y 605CONFIG_FEATURE_WGET_STATUSBAR=y
606CONFIG_FEATURE_WGET_AUTHENTICATION=y 606CONFIG_FEATURE_WGET_AUTHENTICATION=y
607CONFIG_FEATURE_WGET_LONG_OPTIONS=y 607CONFIG_FEATURE_WGET_LONG_OPTIONS=y
608# CONFIG_ZCIP is not set 608CONFIG_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);
263char *xmalloc_readlink_or_warn(const char *path); 263char *xmalloc_readlink_or_warn(const char *path);
264char *xmalloc_realpath(const char *path); 264char *xmalloc_realpath(const char *path);
265extern void xstat(const char *filename, struct stat *buf); 265extern 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 */
266extern int wait4pid(int pid); 273extern int wait4pid(int pid);
267extern void xsetgid(gid_t gid); 274extern void xsetgid(gid_t gid);
268extern void xsetuid(uid_t uid); 275extern 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
73static 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 */
133static int run(const char *script, const char *arg, const char *intf, struct in_addr *ip) 129static 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)
167bad: 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 */
190static const struct in_addr null_ip; // = { 0 };
191static const struct ether_addr null_addr; // = { {0, 0, 0, 0, 0, 0} };
192
193static struct sockaddr saddr; // memset(0);
194static struct in_addr ip; // = { 0 };
195static struct ifreq ifr; //memset(0);
196
197static char *intf; // = NULL;
198static char *script; // = NULL;
199static suseconds_t timeout; // = 0; // milliseconds
200static unsigned conflicts; // = 0;
201static unsigned nprobes; // = 0;
202static unsigned nclaims; // = 0;
203static int ready; // = 0;
204static int verbose; // = 0;
205static int state = PROBE;
206
207int zcip_main(int argc, char *argv[]); 162int zcip_main(int argc, char *argv[]);
208int zcip_main(int argc, char *argv[]) 163int 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 }
545bad: 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}