diff options
author | Ron Yorston <rmy@pobox.com> | 2019-03-31 08:55:48 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-03-31 09:51:00 +0100 |
commit | 61e0e3160a8be3ed8488b09200a5dca1bd1b21b4 (patch) | |
tree | d55341d875d1dd0d77445960723a47418efd14e5 | |
parent | be2949717934c19890879cf2a8fc74c5da55d1c7 (diff) | |
parent | 35082fc2c17369223669e099f422acc0982ee4ff (diff) | |
download | busybox-w32-61e0e3160a8be3ed8488b09200a5dca1bd1b21b4.tar.gz busybox-w32-61e0e3160a8be3ed8488b09200a5dca1bd1b21b4.tar.bz2 busybox-w32-61e0e3160a8be3ed8488b09200a5dca1bd1b21b4.zip |
Merge branch 'busybox' into merge
-rw-r--r-- | editors/vi.c | 19 | ||||
-rw-r--r-- | include/libbb.h | 6 | ||||
-rw-r--r-- | libbb/appletlib.c | 1 | ||||
-rw-r--r-- | libbb/pidfile.c | 18 | ||||
-rw-r--r-- | miscutils/crond.c | 2 | ||||
-rw-r--r-- | miscutils/man.c | 54 | ||||
-rw-r--r-- | miscutils/ts.c | 84 | ||||
-rw-r--r-- | miscutils/watchdog.c | 4 | ||||
-rw-r--r-- | networking/inetd.c | 4 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 4 | ||||
-rw-r--r-- | networking/ntpd.c | 8 | ||||
-rw-r--r-- | shell/ash.c | 53 | ||||
-rw-r--r-- | shell/hush.c | 35 | ||||
-rw-r--r-- | sysklogd/klogd.c | 4 | ||||
-rw-r--r-- | sysklogd/syslogd.c | 4 | ||||
-rw-r--r-- | util-linux/blockdev.c | 139 |
16 files changed, 299 insertions, 140 deletions
diff --git a/editors/vi.c b/editors/vi.c index d5d7dfffc..2a7d9f0a8 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -345,7 +345,8 @@ struct globals { | |||
345 | 345 | ||
346 | /* a few references only */ | 346 | /* a few references only */ |
347 | #if ENABLE_FEATURE_VI_YANKMARK | 347 | #if ENABLE_FEATURE_VI_YANKMARK |
348 | int YDreg, Ureg; // default delete register and orig line for "U" | 348 | smalluint YDreg;//,Ureg;// default delete register and orig line for "U" |
349 | #define Ureg 27 | ||
349 | char *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 | 350 | char *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 |
350 | char *mark[28]; // user marks points somewhere in text[]- a-z and previous context '' | 351 | char *mark[28]; // user marks points somewhere in text[]- a-z and previous context '' |
351 | char *context_start, *context_end; | 352 | char *context_start, *context_end; |
@@ -457,7 +458,7 @@ struct globals { | |||
457 | #define format_edit_status__tot (G.format_edit_status__tot) | 458 | #define format_edit_status__tot (G.format_edit_status__tot) |
458 | 459 | ||
459 | #define YDreg (G.YDreg ) | 460 | #define YDreg (G.YDreg ) |
460 | #define Ureg (G.Ureg ) | 461 | //#define Ureg (G.Ureg ) |
461 | #define mark (G.mark ) | 462 | #define mark (G.mark ) |
462 | #define context_start (G.context_start ) | 463 | #define context_start (G.context_start ) |
463 | #define context_end (G.context_end ) | 464 | #define context_end (G.context_end ) |
@@ -796,7 +797,7 @@ static void edit_file(char *fn) | |||
796 | 797 | ||
797 | #if ENABLE_FEATURE_VI_YANKMARK | 798 | #if ENABLE_FEATURE_VI_YANKMARK |
798 | YDreg = 26; // default Yank/Delete reg | 799 | YDreg = 26; // default Yank/Delete reg |
799 | Ureg = 27; // hold orig line for "U" cmd | 800 | // Ureg = 27; - const // hold orig line for "U" cmd |
800 | mark[26] = mark[27] = text; // init "previous context" | 801 | mark[26] = mark[27] = text; // init "previous context" |
801 | #endif | 802 | #endif |
802 | 803 | ||
@@ -3410,7 +3411,15 @@ static void refresh(int full_screen) | |||
3410 | if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) { | 3411 | if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) { |
3411 | unsigned c = columns, r = rows; | 3412 | unsigned c = columns, r = rows; |
3412 | query_screen_dimensions(); | 3413 | query_screen_dimensions(); |
3414 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
3413 | full_screen |= (c - columns) | (r - rows); | 3415 | full_screen |= (c - columns) | (r - rows); |
3416 | #else | ||
3417 | if (c != columns || r != rows) { | ||
3418 | full_screen = TRUE; | ||
3419 | /* update screen memory since SIGWINCH won't have done it */ | ||
3420 | new_screen(rows, columns); | ||
3421 | } | ||
3422 | #endif | ||
3414 | } | 3423 | } |
3415 | sync_cursor(dot, &crow, &ccol); // where cursor will be (on "dot") | 3424 | sync_cursor(dot, &crow, &ccol); // where cursor will be (on "dot") |
3416 | tp = screenbegin; // index into text[] of top line | 3425 | tp = screenbegin; // index into text[] of top line |
@@ -4236,8 +4245,8 @@ static void do_cmd(int c) | |||
4236 | if (*p == '\n') | 4245 | if (*p == '\n') |
4237 | cnt++; | 4246 | cnt++; |
4238 | } | 4247 | } |
4239 | status_line("%s %d lines (%d chars) using [%c]", | 4248 | status_line("%s %u lines (%u chars) using [%c]", |
4240 | buf, cnt, strlen(reg[YDreg]), what_reg()); | 4249 | buf, cnt, (unsigned)strlen(reg[YDreg]), what_reg()); |
4241 | #endif | 4250 | #endif |
4242 | end_cmd_q(); // stop adding to q | 4251 | end_cmd_q(); // stop adding to q |
4243 | } | 4252 | } |
diff --git a/include/libbb.h b/include/libbb.h index b9852345f..05a0c575c 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1341,9 +1341,13 @@ llist_t *llist_find_str(llist_t *first, const char *str) FAST_FUNC; | |||
1341 | /* True only if we created pidfile which is *file*, not /dev/null etc */ | 1341 | /* True only if we created pidfile which is *file*, not /dev/null etc */ |
1342 | extern smallint wrote_pidfile; | 1342 | extern smallint wrote_pidfile; |
1343 | void write_pidfile(const char *path) FAST_FUNC; | 1343 | void write_pidfile(const char *path) FAST_FUNC; |
1344 | void write_pidfile_std_path_and_ext(const char *path) FAST_FUNC; | ||
1345 | void remove_pidfile_std_path_and_ext(const char *path) FAST_FUNC; | ||
1344 | #define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0) | 1346 | #define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0) |
1345 | #else | 1347 | #else |
1346 | enum { wrote_pidfile = 0 }; | 1348 | enum { wrote_pidfile = 0 }; |
1349 | #define write_pidfile_std_path_and_ext(path) ((void)0) | ||
1350 | #define remove_pidfile_std_path_and_ext(path) ((void)0) | ||
1347 | #define write_pidfile(path) ((void)0) | 1351 | #define write_pidfile(path) ((void)0) |
1348 | #define remove_pidfile(path) ((void)0) | 1352 | #define remove_pidfile(path) ((void)0) |
1349 | #endif | 1353 | #endif |
@@ -1386,7 +1390,7 @@ void bb_logenv_override(void) FAST_FUNC; | |||
1386 | 1390 | ||
1387 | /* Embedded script support */ | 1391 | /* Embedded script support */ |
1388 | char *get_script_content(unsigned n) FAST_FUNC; | 1392 | char *get_script_content(unsigned n) FAST_FUNC; |
1389 | int scripted_main(int argc, char** argv); | 1393 | int scripted_main(int argc, char** argv) MAIN_EXTERNALLY_VISIBLE; |
1390 | 1394 | ||
1391 | /* Applets which are useful from another applets */ | 1395 | /* Applets which are useful from another applets */ |
1392 | int bb_cat(char** argv) FAST_FUNC; | 1396 | int bb_cat(char** argv) FAST_FUNC; |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 58e391fd9..1f1a18aab 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -814,6 +814,7 @@ static int find_script_by_name(const char *name) | |||
814 | return -1; | 814 | return -1; |
815 | } | 815 | } |
816 | 816 | ||
817 | int scripted_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
817 | int scripted_main(int argc UNUSED_PARAM, char **argv) | 818 | int scripted_main(int argc UNUSED_PARAM, char **argv) |
818 | { | 819 | { |
819 | int script = find_script_by_name(applet_name); | 820 | int script = find_script_by_name(applet_name); |
diff --git a/libbb/pidfile.c b/libbb/pidfile.c index a48dfc38b..a6a282562 100644 --- a/libbb/pidfile.c +++ b/libbb/pidfile.c | |||
@@ -38,3 +38,21 @@ void FAST_FUNC write_pidfile(const char *path) | |||
38 | } | 38 | } |
39 | close(pid_fd); | 39 | close(pid_fd); |
40 | } | 40 | } |
41 | |||
42 | void FAST_FUNC write_pidfile_std_path_and_ext(const char *name) | ||
43 | { | ||
44 | char buf[sizeof(CONFIG_PID_FILE_PATH) + 64]; | ||
45 | |||
46 | snprintf(buf, sizeof(buf), CONFIG_PID_FILE_PATH"/%s.pid", name); | ||
47 | write_pidfile(buf); | ||
48 | } | ||
49 | |||
50 | void FAST_FUNC remove_pidfile_std_path_and_ext(const char *name) | ||
51 | { | ||
52 | char buf[sizeof(CONFIG_PID_FILE_PATH) + 64]; | ||
53 | |||
54 | if (!wrote_pidfile) | ||
55 | return; | ||
56 | snprintf(buf, sizeof(buf), CONFIG_PID_FILE_PATH"/%s.pid", name); | ||
57 | unlink(buf); | ||
58 | } | ||
diff --git a/miscutils/crond.c b/miscutils/crond.c index 2e36c406b..25e5503c7 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -1056,7 +1056,7 @@ int crond_main(int argc UNUSED_PARAM, char **argv) | |||
1056 | 1056 | ||
1057 | log8("crond (busybox "BB_VER") started, log level %d", G.log_level); | 1057 | log8("crond (busybox "BB_VER") started, log level %d", G.log_level); |
1058 | rescan_crontab_dir(); | 1058 | rescan_crontab_dir(); |
1059 | write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid"); | 1059 | write_pidfile_std_path_and_ext("crond"); |
1060 | #if ENABLE_FEATURE_CROND_SPECIAL_TIMES | 1060 | #if ENABLE_FEATURE_CROND_SPECIAL_TIMES |
1061 | if (touch_reboot_file()) | 1061 | if (touch_reboot_file()) |
1062 | start_jobs(START_ME_REBOOT); /* start @reboot entries, if any */ | 1062 | start_jobs(START_ME_REBOOT); /* start @reboot entries, if any */ |
diff --git a/miscutils/man.c b/miscutils/man.c index 0bc11e623..6724b4b5d 100644 --- a/miscutils/man.c +++ b/miscutils/man.c | |||
@@ -13,9 +13,9 @@ | |||
13 | //kbuild:lib-$(CONFIG_MAN) += man.o | 13 | //kbuild:lib-$(CONFIG_MAN) += man.o |
14 | 14 | ||
15 | //usage:#define man_trivial_usage | 15 | //usage:#define man_trivial_usage |
16 | //usage: "[-aw] [MANPAGE]..." | 16 | //usage: "[-aw] MANPAGE..." |
17 | //usage:#define man_full_usage "\n\n" | 17 | //usage:#define man_full_usage "\n\n" |
18 | //usage: "Format and display manual page\n" | 18 | //usage: "Display manual page\n" |
19 | //usage: "\n -a Display all pages" | 19 | //usage: "\n -a Display all pages" |
20 | //usage: "\n -w Show page locations" | 20 | //usage: "\n -w Show page locations" |
21 | //usage: "\n" | 21 | //usage: "\n" |
@@ -209,9 +209,6 @@ static char **add_MANPATH(char **man_path_list, int *count_mp, char *path) | |||
209 | path_element = man_path_list; | 209 | path_element = man_path_list; |
210 | if (path_element) while (*path_element) { | 210 | if (path_element) while (*path_element) { |
211 | if (strcmp(*path_element, path) == 0) { | 211 | if (strcmp(*path_element, path) == 0) { |
212 | /* Have path but haven't counted it, must be default */ | ||
213 | if (*count_mp == 0) | ||
214 | break; | ||
215 | goto skip; | 212 | goto skip; |
216 | } | 213 | } |
217 | path_element++; | 214 | path_element++; |
@@ -247,14 +244,14 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
247 | { | 244 | { |
248 | parser_t *parser; | 245 | parser_t *parser; |
249 | char *sec_list; | 246 | char *sec_list; |
250 | char *cur_path, *cur_sect; | ||
251 | char **man_path_list; | 247 | char **man_path_list; |
252 | int count_mp; | 248 | int count_mp; |
253 | int cur_mp; | ||
254 | int opt, not_found; | 249 | int opt, not_found; |
255 | char *token[2]; | 250 | char *token[2]; |
256 | #if ENABLE_PLATFORM_MINGW32 | 251 | #if ENABLE_PLATFORM_MINGW32 |
257 | char **ptr; | 252 | char **ptr; |
253 | char *exepath, *relpath; | ||
254 | const char *mpl[] = { "/usr/man", "/usr/share/man", NULL, NULL }; | ||
258 | #endif | 255 | #endif |
259 | 256 | ||
260 | INIT_G(); | 257 | INIT_G(); |
@@ -276,16 +273,6 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
276 | man_path_list = add_MANPATH(NULL, &count_mp, | 273 | man_path_list = add_MANPATH(NULL, &count_mp, |
277 | getenv("MANDATORY_MANPATH"+10) /* "MANPATH" */ | 274 | getenv("MANDATORY_MANPATH"+10) /* "MANPATH" */ |
278 | ); | 275 | ); |
279 | if (!man_path_list) { | ||
280 | /* default, may be overridden by /etc/man.conf */ | ||
281 | man_path_list = xzalloc(2 * sizeof(man_path_list[0])); | ||
282 | man_path_list[0] = (char*)"/usr/man"; | ||
283 | /* count_mp stays 0. | ||
284 | * Thus, man.conf will overwrite man_path_list[0] | ||
285 | * if a path is defined there. | ||
286 | */ | ||
287 | } | ||
288 | |||
289 | /* Parse man.conf[ig] or man_db.conf */ | 276 | /* Parse man.conf[ig] or man_db.conf */ |
290 | /* man version 1.6f uses man.config */ | 277 | /* man version 1.6f uses man.config */ |
291 | /* man-db implementation of man uses man_db.conf */ | 278 | /* man-db implementation of man uses man_db.conf */ |
@@ -299,7 +286,7 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
299 | if (!token[1]) | 286 | if (!token[1]) |
300 | continue; | 287 | continue; |
301 | if (strcmp("DEFINE", token[0]) == 0) { | 288 | if (strcmp("DEFINE", token[0]) == 0) { |
302 | G.col = if_redefined(G.tbl , "col", token[1]); | 289 | G.col = if_redefined(G.col , "col", token[1]); |
303 | G.tbl = if_redefined(G.tbl , "tbl", token[1]); | 290 | G.tbl = if_redefined(G.tbl , "tbl", token[1]); |
304 | G.nroff = if_redefined(G.nroff, "nroff", token[1]); | 291 | G.nroff = if_redefined(G.nroff, "nroff", token[1]); |
305 | G.pager = if_redefined(G.pager, "pager", token[1]); | 292 | G.pager = if_redefined(G.pager, "pager", token[1]); |
@@ -317,17 +304,22 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
317 | config_close(parser); | 304 | config_close(parser); |
318 | 305 | ||
319 | #if ENABLE_PLATFORM_MINGW32 | 306 | #if ENABLE_PLATFORM_MINGW32 |
320 | { | 307 | /* allow man pages to be stored relative to the executable */ |
321 | char *exepath = xstrdup(bb_busybox_exec_path); | 308 | exepath = xstrdup(bb_busybox_exec_path); |
322 | char *relpath = concat_path_file(dirname(exepath), "man"); | 309 | relpath = concat_path_file(dirname(exepath), "man"); |
323 | if (count_mp == 0) { | 310 | |
324 | /* default must match path set above */ | 311 | if (!man_path_list) { |
325 | man_path_list = add_MANPATH(man_path_list, &count_mp, | 312 | mpl[2] = relpath; |
326 | (char *)"/usr/man"); | 313 | man_path_list = (char**)mpl; |
327 | } | 314 | } |
315 | else { | ||
328 | man_path_list = add_MANPATH(man_path_list, &count_mp, relpath); | 316 | man_path_list = add_MANPATH(man_path_list, &count_mp, relpath); |
329 | free(relpath); | 317 | } |
330 | free(exepath); | 318 | #else |
319 | if (!man_path_list) { | ||
320 | static const char *const mpl[] = { "/usr/man", "/usr/share/man", NULL }; | ||
321 | man_path_list = (char**)mpl; | ||
322 | /*count_mp = 2; - not used below anyway */ | ||
331 | } | 323 | } |
332 | #endif | 324 | #endif |
333 | 325 | ||
@@ -347,16 +339,18 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
347 | 339 | ||
348 | not_found = 0; | 340 | not_found = 0; |
349 | do { /* for each argv[] */ | 341 | do { /* for each argv[] */ |
342 | const char *cur_path; | ||
343 | int cur_mp; | ||
350 | int found = 0; | 344 | int found = 0; |
351 | cur_mp = 0; | ||
352 | 345 | ||
353 | if (strchr(*argv, '/')) { | 346 | if (strchr(*argv, '/')) { |
354 | found = show_manpage(*argv, /*man:*/ 1, 0); | 347 | found = show_manpage(*argv, /*man:*/ 1, 0); |
355 | goto check_found; | 348 | goto check_found; |
356 | } | 349 | } |
350 | cur_mp = 0; | ||
357 | while ((cur_path = man_path_list[cur_mp++]) != NULL) { | 351 | while ((cur_path = man_path_list[cur_mp++]) != NULL) { |
358 | /* for each MANPATH */ | 352 | /* for each MANPATH */ |
359 | cur_sect = sec_list; | 353 | const char *cur_sect = sec_list; |
360 | do { /* for each section */ | 354 | do { /* for each section */ |
361 | char *next_sect = strchrnul(cur_sect, ':'); | 355 | char *next_sect = strchrnul(cur_sect, ':'); |
362 | int sect_len = next_sect - cur_sect; | 356 | int sect_len = next_sect - cur_sect; |
diff --git a/miscutils/ts.c b/miscutils/ts.c new file mode 100644 index 000000000..f2d367654 --- /dev/null +++ b/miscutils/ts.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2019 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | //config:config TS | ||
7 | //config: bool "ts (450 bytes)" | ||
8 | //config: default y | ||
9 | |||
10 | //applet:IF_TS(APPLET(ts, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
11 | |||
12 | //kbuild:lib-$(CONFIG_TS) += ts.o | ||
13 | |||
14 | //usage:#define ts_trivial_usage | ||
15 | //usage: "[-is] [STRFTIME]" | ||
16 | //usage:#define ts_full_usage "" | ||
17 | |||
18 | #include "libbb.h" | ||
19 | #include "common_bufsiz.h" | ||
20 | |||
21 | int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
22 | int ts_main(int argc UNUSED_PARAM, char **argv) | ||
23 | { | ||
24 | struct timeval base; | ||
25 | unsigned opt; | ||
26 | char *frac; | ||
27 | char *fmt_dt2str; | ||
28 | char *line; | ||
29 | |||
30 | opt = getopt32(argv, "^" "is" "\0" "?1" /*max one arg*/); | ||
31 | if (opt) { | ||
32 | putenv((char*)"TZ=UTC0"); | ||
33 | tzset(); | ||
34 | } | ||
35 | /*argc -= optind;*/ | ||
36 | argv += optind; | ||
37 | fmt_dt2str = argv[0] ? argv[0] | ||
38 | : (char*)(opt ? "%b %d %H:%M:%S"+6 : "%b %d %H:%M:%S"); | ||
39 | frac = is_suffixed_with(fmt_dt2str, "%.S"); | ||
40 | if (!frac) | ||
41 | frac = is_suffixed_with(fmt_dt2str, "%.s"); | ||
42 | if (frac) { | ||
43 | frac++; | ||
44 | frac[0] = frac[1]; | ||
45 | frac[1] = '\0'; | ||
46 | } | ||
47 | |||
48 | #define date_buf bb_common_bufsiz1 | ||
49 | setup_common_bufsiz(); | ||
50 | gettimeofday(&base, NULL); | ||
51 | |||
52 | while ((line = xmalloc_fgets(stdin)) != NULL) { | ||
53 | struct timeval ts; | ||
54 | struct tm tm_time; | ||
55 | |||
56 | gettimeofday(&ts, NULL); | ||
57 | if (opt) { | ||
58 | /* -i and/or -s */ | ||
59 | struct timeval ts1 = ts1; | ||
60 | if (opt & 1) /* -i */ | ||
61 | ts1 = ts; | ||
62 | //printf("%d %d\n", ts.tv_sec, base.tv_sec); | ||
63 | ts.tv_sec -= base.tv_sec; | ||
64 | //printf("%d %d\n", ts.tv_sec, base.tv_sec); | ||
65 | ts.tv_usec -= base.tv_usec; | ||
66 | if ((int32_t)(ts.tv_usec) < 0) { | ||
67 | ts.tv_sec--; | ||
68 | ts.tv_usec += 1000*1000; | ||
69 | } | ||
70 | if (opt & 1) /* -i */ | ||
71 | base = ts1; | ||
72 | } | ||
73 | localtime_r(&ts.tv_sec, &tm_time); | ||
74 | strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time); | ||
75 | if (!frac) { | ||
76 | printf("%s %s", date_buf, line); | ||
77 | } else { | ||
78 | printf("%s.%06u %s", date_buf, (unsigned)ts.tv_usec, line); | ||
79 | } | ||
80 | free(line); | ||
81 | } | ||
82 | |||
83 | return EXIT_SUCCESS; | ||
84 | } | ||
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index 1e9ecc5e8..86600b72f 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c | |||
@@ -64,7 +64,7 @@ static void shutdown_watchdog(void) | |||
64 | 64 | ||
65 | static void shutdown_on_signal(int sig UNUSED_PARAM) | 65 | static void shutdown_on_signal(int sig UNUSED_PARAM) |
66 | { | 66 | { |
67 | remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid"); | 67 | remove_pidfile_std_path_and_ext("watchdog"); |
68 | shutdown_watchdog(); | 68 | shutdown_watchdog(); |
69 | _exit(EXIT_SUCCESS); | 69 | _exit(EXIT_SUCCESS); |
70 | } | 70 | } |
@@ -136,7 +136,7 @@ int watchdog_main(int argc UNUSED_PARAM, char **argv) | |||
136 | stimer_duration, htimer_duration * 1000); | 136 | stimer_duration, htimer_duration * 1000); |
137 | #endif | 137 | #endif |
138 | 138 | ||
139 | write_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid"); | 139 | write_pidfile_std_path_and_ext("watchdog"); |
140 | 140 | ||
141 | while (1) { | 141 | while (1) { |
142 | /* | 142 | /* |
diff --git a/networking/inetd.c b/networking/inetd.c index 8f871ee12..da6551174 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -1207,7 +1207,7 @@ static void clean_up_and_exit(int sig UNUSED_PARAM) | |||
1207 | if (ENABLE_FEATURE_CLEAN_UP) | 1207 | if (ENABLE_FEATURE_CLEAN_UP) |
1208 | close(sep->se_fd); | 1208 | close(sep->se_fd); |
1209 | } | 1209 | } |
1210 | remove_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); | 1210 | remove_pidfile_std_path_and_ext("inetd"); |
1211 | exit(EXIT_SUCCESS); | 1211 | exit(EXIT_SUCCESS); |
1212 | } | 1212 | } |
1213 | 1213 | ||
@@ -1256,7 +1256,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1256 | setgroups(1, &gid); | 1256 | setgroups(1, &gid); |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | write_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); | 1259 | write_pidfile_std_path_and_ext("inetd"); |
1260 | 1260 | ||
1261 | /* never fails under Linux (except if you pass it bad arguments) */ | 1261 | /* never fails under Linux (except if you pass it bad arguments) */ |
1262 | getrlimit(RLIMIT_NOFILE, &rlim_ofile); | 1262 | getrlimit(RLIMIT_NOFILE, &rlim_ofile); |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index d088caf4c..0a1b5d798 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -574,8 +574,8 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) | |||
574 | } | 574 | } |
575 | 575 | ||
576 | for (l = linfo; l; l = l->next) { | 576 | for (l = linfo; l; l = l->next) { |
577 | if (no_link | 577 | if ((oneline && G_filter.family != AF_PACKET) |
578 | || (oneline || print_linkinfo(&l->h) == 0) | 578 | || (print_linkinfo(&l->h) == 0) |
579 | /* ^^^^^^^^^ "ip -oneline a" does not print link info */ | 579 | /* ^^^^^^^^^ "ip -oneline a" does not print link info */ |
580 | ) { | 580 | ) { |
581 | struct ifinfomsg *ifi = NLMSG_DATA(&l->h); | 581 | struct ifinfomsg *ifi = NLMSG_DATA(&l->h); |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 0f474bc09..027cfe783 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -2585,6 +2585,10 @@ static NOINLINE void ntp_init(char **argv) | |||
2585 | /* -l but no peers: "stratum 1 server" mode */ | 2585 | /* -l but no peers: "stratum 1 server" mode */ |
2586 | G.stratum = 1; | 2586 | G.stratum = 1; |
2587 | } | 2587 | } |
2588 | |||
2589 | if (!(opts & OPT_n)) /* only if backgrounded: */ | ||
2590 | write_pidfile_std_path_and_ext("ntpd"); | ||
2591 | |||
2588 | /* If network is up, syncronization occurs in ~10 seconds. | 2592 | /* If network is up, syncronization occurs in ~10 seconds. |
2589 | * We give "ntpd -q" 10 seconds to get first reply, | 2593 | * We give "ntpd -q" 10 seconds to get first reply, |
2590 | * then another 50 seconds to finish syncing. | 2594 | * then another 50 seconds to finish syncing. |
@@ -2641,8 +2645,6 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2641 | */ | 2645 | */ |
2642 | cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); | 2646 | cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); |
2643 | 2647 | ||
2644 | write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); | ||
2645 | |||
2646 | while (!bb_got_signal) { | 2648 | while (!bb_got_signal) { |
2647 | llist_t *item; | 2649 | llist_t *item; |
2648 | unsigned i, j; | 2650 | unsigned i, j; |
@@ -2814,7 +2816,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2814 | } | 2816 | } |
2815 | } /* while (!bb_got_signal) */ | 2817 | } /* while (!bb_got_signal) */ |
2816 | 2818 | ||
2817 | remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); | 2819 | remove_pidfile_std_path_and_ext("ntpd"); |
2818 | kill_myself_with_sig(bb_got_signal); | 2820 | kill_myself_with_sig(bb_got_signal); |
2819 | } | 2821 | } |
2820 | 2822 | ||
diff --git a/shell/ash.c b/shell/ash.c index 5f64bebe3..8a3c3ae35 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -3866,7 +3866,7 @@ struct procstat { | |||
3866 | 3866 | ||
3867 | struct job { | 3867 | struct job { |
3868 | struct procstat ps0; /* status of process */ | 3868 | struct procstat ps0; /* status of process */ |
3869 | struct procstat *ps; /* status or processes when more than one */ | 3869 | struct procstat *ps; /* status of processes when more than one */ |
3870 | #if JOBS | 3870 | #if JOBS |
3871 | int stopstatus; /* status of a stopped job */ | 3871 | int stopstatus; /* status of a stopped job */ |
3872 | #endif | 3872 | #endif |
@@ -4703,6 +4703,9 @@ wait_block_or_sig(int *status) | |||
4703 | #define DOWAIT_NONBLOCK 0 | 4703 | #define DOWAIT_NONBLOCK 0 |
4704 | #define DOWAIT_BLOCK 1 | 4704 | #define DOWAIT_BLOCK 1 |
4705 | #define DOWAIT_BLOCK_OR_SIG 2 | 4705 | #define DOWAIT_BLOCK_OR_SIG 2 |
4706 | #if ENABLE_ASH_BASH_COMPAT | ||
4707 | # define DOWAIT_JOBSTATUS 0x10 /* OR this to get job's exitstatus instead of pid */ | ||
4708 | #endif | ||
4706 | 4709 | ||
4707 | static int | 4710 | static int |
4708 | dowait(int block, struct job *job) | 4711 | dowait(int block, struct job *job) |
@@ -4710,7 +4713,11 @@ dowait(int block, struct job *job) | |||
4710 | int pid; | 4713 | int pid; |
4711 | int status; | 4714 | int status; |
4712 | struct job *jp; | 4715 | struct job *jp; |
4713 | struct job *thisjob = NULL; | 4716 | struct job *thisjob; |
4717 | #if ENABLE_ASH_BASH_COMPAT | ||
4718 | bool want_jobexitstatus = (block & DOWAIT_JOBSTATUS); | ||
4719 | block = (block & ~DOWAIT_JOBSTATUS); | ||
4720 | #endif | ||
4714 | 4721 | ||
4715 | TRACE(("dowait(0x%x) called\n", block)); | 4722 | TRACE(("dowait(0x%x) called\n", block)); |
4716 | 4723 | ||
@@ -4747,10 +4754,10 @@ dowait(int block, struct job *job) | |||
4747 | } | 4754 | } |
4748 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", | 4755 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", |
4749 | pid, status, errno, strerror(errno))); | 4756 | pid, status, errno, strerror(errno))); |
4757 | thisjob = NULL; | ||
4750 | if (pid <= 0) | 4758 | if (pid <= 0) |
4751 | goto out; | 4759 | goto out; |
4752 | 4760 | ||
4753 | thisjob = NULL; | ||
4754 | for (jp = curjob; jp; jp = jp->prev_job) { | 4761 | for (jp = curjob; jp; jp = jp->prev_job) { |
4755 | int jobstate; | 4762 | int jobstate; |
4756 | struct procstat *ps; | 4763 | struct procstat *ps; |
@@ -4814,6 +4821,13 @@ dowait(int block, struct job *job) | |||
4814 | out: | 4821 | out: |
4815 | INT_ON; | 4822 | INT_ON; |
4816 | 4823 | ||
4824 | #if ENABLE_ASH_BASH_COMPAT | ||
4825 | if (want_jobexitstatus) { | ||
4826 | pid = -1; | ||
4827 | if (thisjob && thisjob->state == JOBDONE) | ||
4828 | pid = thisjob->ps[thisjob->nprocs - 1].ps_status; | ||
4829 | } | ||
4830 | #endif | ||
4817 | if (thisjob && thisjob == job) { | 4831 | if (thisjob && thisjob == job) { |
4818 | char s[48 + 1]; | 4832 | char s[48 + 1]; |
4819 | int len; | 4833 | int len; |
@@ -4996,15 +5010,24 @@ waitcmd(int argc UNUSED_PARAM, char **argv) | |||
4996 | struct job *job; | 5010 | struct job *job; |
4997 | int retval; | 5011 | int retval; |
4998 | struct job *jp; | 5012 | struct job *jp; |
4999 | 5013 | #if ENABLE_ASH_BASH_COMPAT | |
5014 | int status; | ||
5015 | char one = nextopt("n"); | ||
5016 | #else | ||
5000 | nextopt(nullstr); | 5017 | nextopt(nullstr); |
5018 | #endif | ||
5001 | retval = 0; | 5019 | retval = 0; |
5002 | 5020 | ||
5003 | argv = argptr; | 5021 | argv = argptr; |
5004 | if (!*argv) { | 5022 | if (!argv[0]) { |
5005 | /* wait for all jobs */ | 5023 | /* wait for all jobs / one job if -n */ |
5006 | for (;;) { | 5024 | for (;;) { |
5007 | jp = curjob; | 5025 | jp = curjob; |
5026 | #if ENABLE_ASH_BASH_COMPAT | ||
5027 | if (one && !jp) | ||
5028 | /* exitcode of "wait -n" with nothing to wait for is 127, not 0 */ | ||
5029 | retval = 127; | ||
5030 | #endif | ||
5008 | while (1) { | 5031 | while (1) { |
5009 | if (!jp) /* no running procs */ | 5032 | if (!jp) /* no running procs */ |
5010 | goto ret; | 5033 | goto ret; |
@@ -5020,13 +5043,31 @@ waitcmd(int argc UNUSED_PARAM, char **argv) | |||
5020 | * with an exit status greater than 128, immediately after which | 5043 | * with an exit status greater than 128, immediately after which |
5021 | * the trap is executed." | 5044 | * the trap is executed." |
5022 | */ | 5045 | */ |
5046 | #if ENABLE_ASH_BASH_COMPAT | ||
5047 | status = dowait(DOWAIT_BLOCK_OR_SIG | DOWAIT_JOBSTATUS, NULL); | ||
5048 | #else | ||
5023 | dowait(DOWAIT_BLOCK_OR_SIG, NULL); | 5049 | dowait(DOWAIT_BLOCK_OR_SIG, NULL); |
5050 | #endif | ||
5024 | /* if child sends us a signal *and immediately exits*, | 5051 | /* if child sends us a signal *and immediately exits*, |
5025 | * dowait() returns pid > 0. Check this case, | 5052 | * dowait() returns pid > 0. Check this case, |
5026 | * not "if (dowait() < 0)"! | 5053 | * not "if (dowait() < 0)"! |
5027 | */ | 5054 | */ |
5028 | if (pending_sig) | 5055 | if (pending_sig) |
5029 | goto sigout; | 5056 | goto sigout; |
5057 | #if ENABLE_ASH_BASH_COMPAT | ||
5058 | if (one) { | ||
5059 | /* wait -n waits for one _job_, not one _process_. | ||
5060 | * date; sleep 3 & sleep 2 | sleep 1 & wait -n; date | ||
5061 | * should wait for 2 seconds. Not 1 or 3. | ||
5062 | */ | ||
5063 | if (status != -1 && !WIFSTOPPED(status)) { | ||
5064 | retval = WEXITSTATUS(status); | ||
5065 | if (WIFSIGNALED(status)) | ||
5066 | retval = WTERMSIG(status) + 128; | ||
5067 | goto ret; | ||
5068 | } | ||
5069 | } | ||
5070 | #endif | ||
5030 | } | 5071 | } |
5031 | } | 5072 | } |
5032 | 5073 | ||
diff --git a/shell/hush.c b/shell/hush.c index 920a85299..fa9afa38e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -923,7 +923,7 @@ struct globals { | |||
923 | # define G_flag_return_in_progress 0 | 923 | # define G_flag_return_in_progress 0 |
924 | #endif | 924 | #endif |
925 | smallint exiting; /* used to prevent EXIT trap recursion */ | 925 | smallint exiting; /* used to prevent EXIT trap recursion */ |
926 | /* These support $?, $#, and $1 */ | 926 | /* These support $? */ |
927 | smalluint last_exitcode; | 927 | smalluint last_exitcode; |
928 | smalluint expand_exitcode; | 928 | smalluint expand_exitcode; |
929 | smalluint last_bg_pid_exitcode; | 929 | smalluint last_bg_pid_exitcode; |
@@ -934,6 +934,9 @@ struct globals { | |||
934 | #else | 934 | #else |
935 | # define G_global_args_malloced 0 | 935 | # define G_global_args_malloced 0 |
936 | #endif | 936 | #endif |
937 | #if ENABLE_HUSH_BASH_COMPAT | ||
938 | int dead_job_exitcode; /* for "wait -n" */ | ||
939 | #endif | ||
937 | /* how many non-NULL argv's we have. NB: $# + 1 */ | 940 | /* how many non-NULL argv's we have. NB: $# + 1 */ |
938 | int global_argc; | 941 | int global_argc; |
939 | char **global_argv; | 942 | char **global_argv; |
@@ -8657,6 +8660,9 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) | |||
8657 | pi->cmds[i].pid = 0; | 8660 | pi->cmds[i].pid = 0; |
8658 | pi->alive_cmds--; | 8661 | pi->alive_cmds--; |
8659 | if (!pi->alive_cmds) { | 8662 | if (!pi->alive_cmds) { |
8663 | #if ENABLE_HUSH_BASH_COMPAT | ||
8664 | G.dead_job_exitcode = job_exited_or_stopped(pi); | ||
8665 | #endif | ||
8660 | if (G_interactive_fd) { | 8666 | if (G_interactive_fd) { |
8661 | printf(JOB_STATUS_FORMAT, pi->jobid, | 8667 | printf(JOB_STATUS_FORMAT, pi->jobid, |
8662 | "Done", pi->cmdtext); | 8668 | "Done", pi->cmdtext); |
@@ -8763,7 +8769,7 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) | |||
8763 | /* fg_pipe exited or stopped */ | 8769 | /* fg_pipe exited or stopped */ |
8764 | break; | 8770 | break; |
8765 | } | 8771 | } |
8766 | if (childpid == waitfor_pid) { | 8772 | if (childpid == waitfor_pid) { /* "wait PID" */ |
8767 | debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); | 8773 | debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); |
8768 | rcode = WEXITSTATUS(status); | 8774 | rcode = WEXITSTATUS(status); |
8769 | if (WIFSIGNALED(status)) | 8775 | if (WIFSIGNALED(status)) |
@@ -8774,6 +8780,15 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) | |||
8774 | rcode++; | 8780 | rcode++; |
8775 | break; /* "wait PID" called us, give it exitcode+1 */ | 8781 | break; /* "wait PID" called us, give it exitcode+1 */ |
8776 | } | 8782 | } |
8783 | #if ENABLE_HUSH_BASH_COMPAT | ||
8784 | if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */ | ||
8785 | && G.dead_job_exitcode >= 0 /* some job did finish */ | ||
8786 | ) { | ||
8787 | debug_printf_exec("waitfor_pid:-1\n"); | ||
8788 | rcode = G.dead_job_exitcode + 1; | ||
8789 | break; | ||
8790 | } | ||
8791 | #endif | ||
8777 | /* This wasn't one of our processes, or */ | 8792 | /* This wasn't one of our processes, or */ |
8778 | /* fg_pipe still has running processes, do waitpid again */ | 8793 | /* fg_pipe still has running processes, do waitpid again */ |
8779 | } /* while (waitpid succeeds)... */ | 8794 | } /* while (waitpid succeeds)... */ |
@@ -11471,6 +11486,12 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |||
11471 | ret--; | 11486 | ret--; |
11472 | if (ret < 0) /* if ECHILD, may need to fix "ret" */ | 11487 | if (ret < 0) /* if ECHILD, may need to fix "ret" */ |
11473 | ret = 0; | 11488 | ret = 0; |
11489 | #if ENABLE_HUSH_BASH_COMPAT | ||
11490 | if (waitfor_pid == -1 && errno == ECHILD) { | ||
11491 | /* exitcode of "wait -n" with no children is 127, not 0 */ | ||
11492 | ret = 127; | ||
11493 | } | ||
11494 | #endif | ||
11474 | sigprocmask(SIG_SETMASK, &oldset, NULL); | 11495 | sigprocmask(SIG_SETMASK, &oldset, NULL); |
11475 | break; | 11496 | break; |
11476 | } | 11497 | } |
@@ -11499,6 +11520,14 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
11499 | int status; | 11520 | int status; |
11500 | 11521 | ||
11501 | argv = skip_dash_dash(argv); | 11522 | argv = skip_dash_dash(argv); |
11523 | #if ENABLE_HUSH_BASH_COMPAT | ||
11524 | if (argv[0] && strcmp(argv[0], "-n") == 0) { | ||
11525 | /* wait -n */ | ||
11526 | /* (bash accepts "wait -n PID" too and ignores PID) */ | ||
11527 | G.dead_job_exitcode = -1; | ||
11528 | return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/); | ||
11529 | } | ||
11530 | #endif | ||
11502 | if (argv[0] == NULL) { | 11531 | if (argv[0] == NULL) { |
11503 | /* Don't care about wait results */ | 11532 | /* Don't care about wait results */ |
11504 | /* Note 1: must wait until there are no more children */ | 11533 | /* Note 1: must wait until there are no more children */ |
@@ -11516,7 +11545,7 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
11516 | * ^C <-- after ~4 sec from keyboard | 11545 | * ^C <-- after ~4 sec from keyboard |
11517 | * $ | 11546 | * $ |
11518 | */ | 11547 | */ |
11519 | return wait_for_child_or_signal(NULL, 0 /*(no job and no pid to wait for)*/); | 11548 | return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/); |
11520 | } | 11549 | } |
11521 | 11550 | ||
11522 | do { | 11551 | do { |
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 76eccf1da..17b6ca235 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c | |||
@@ -231,7 +231,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
231 | 231 | ||
232 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); | 232 | syslog(LOG_NOTICE, "klogd started: %s", bb_banner); |
233 | 233 | ||
234 | write_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid"); | 234 | write_pidfile_std_path_and_ext("klogd"); |
235 | 235 | ||
236 | used = 0; | 236 | used = 0; |
237 | while (!bb_got_signal) { | 237 | while (!bb_got_signal) { |
@@ -295,7 +295,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) | |||
295 | 295 | ||
296 | klogd_close(); | 296 | klogd_close(); |
297 | syslog(LOG_NOTICE, "klogd: exiting"); | 297 | syslog(LOG_NOTICE, "klogd: exiting"); |
298 | remove_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid"); | 298 | remove_pidfile_std_path_and_ext("klogd"); |
299 | if (bb_got_signal) | 299 | if (bb_got_signal) |
300 | kill_myself_with_sig(bb_got_signal); | 300 | kill_myself_with_sig(bb_got_signal); |
301 | return EXIT_FAILURE; | 301 | return EXIT_FAILURE; |
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index f12359476..d0dd1bd20 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -1098,7 +1098,7 @@ static void do_syslogd(void) | |||
1098 | } /* while (!bb_got_signal) */ | 1098 | } /* while (!bb_got_signal) */ |
1099 | 1099 | ||
1100 | timestamp_and_log_internal("syslogd exiting"); | 1100 | timestamp_and_log_internal("syslogd exiting"); |
1101 | remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); | 1101 | remove_pidfile_std_path_and_ext("syslogd"); |
1102 | ipcsyslog_cleanup(); | 1102 | ipcsyslog_cleanup(); |
1103 | if (option_mask32 & OPT_kmsg) | 1103 | if (option_mask32 & OPT_kmsg) |
1104 | kmsg_cleanup(); | 1104 | kmsg_cleanup(); |
@@ -1164,7 +1164,7 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv) | |||
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | //umask(0); - why?? | 1166 | //umask(0); - why?? |
1167 | write_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); | 1167 | write_pidfile_std_path_and_ext("syslogd"); |
1168 | 1168 | ||
1169 | do_syslogd(); | 1169 | do_syslogd(); |
1170 | /* return EXIT_SUCCESS; */ | 1170 | /* return EXIT_SUCCESS; */ |
diff --git a/util-linux/blockdev.c b/util-linux/blockdev.c index 5d8e465b4..e9b5b8bf9 100644 --- a/util-linux/blockdev.c +++ b/util-linux/blockdev.c | |||
@@ -34,6 +34,35 @@ | |||
34 | #include "libbb.h" | 34 | #include "libbb.h" |
35 | #include <linux/fs.h> | 35 | #include <linux/fs.h> |
36 | 36 | ||
37 | /* Takes less space is separate arrays than one array of struct */ | ||
38 | static const char bdcmd_names[] ALIGN1 = | ||
39 | "setro" "\0" | ||
40 | #define CMD_SETRO 0 | ||
41 | "setrw" "\0" | ||
42 | "getro" "\0" | ||
43 | "getss" "\0" | ||
44 | "getbsz" "\0" | ||
45 | "setbsz" "\0" | ||
46 | #define CMD_SETBSZ 5 | ||
47 | "getsz" "\0" | ||
48 | "getsize" "\0" | ||
49 | "getsize64" "\0" | ||
50 | "flushbufs" "\0" | ||
51 | "rereadpt" "\0" | ||
52 | ; | ||
53 | static const uint32_t bdcmd_ioctl[] = { | ||
54 | BLKROSET, //setro | ||
55 | BLKROSET, //setrw | ||
56 | BLKROGET, //getro | ||
57 | BLKSSZGET, //getss | ||
58 | BLKBSZGET, //getbsz | ||
59 | BLKBSZSET, //setbsz | ||
60 | BLKGETSIZE64, //getsz | ||
61 | BLKGETSIZE, //getsize | ||
62 | BLKGETSIZE64, //getsize64 | ||
63 | BLKFLSBUF, //flushbufs | ||
64 | BLKRRPART, //rereadpt | ||
65 | }; | ||
37 | enum { | 66 | enum { |
38 | ARG_NONE = 0, | 67 | ARG_NONE = 0, |
39 | ARG_INT = 1, | 68 | ARG_INT = 1, |
@@ -46,83 +75,26 @@ enum { | |||
46 | FL_NORESULT = 8, | 75 | FL_NORESULT = 8, |
47 | FL_SCALE512 = 16, | 76 | FL_SCALE512 = 16, |
48 | }; | 77 | }; |
49 | 78 | static const uint8_t bdcmd_flags[] ALIGN1 = { | |
50 | struct bdc { | 79 | ARG_INT + FL_NORESULT, //setro |
51 | uint32_t ioc; /* ioctl code */ | 80 | ARG_INT + FL_NORESULT, //setrw |
52 | const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */ | 81 | ARG_INT, //getro |
53 | uint8_t flags; | 82 | ARG_INT, //getss |
54 | int8_t argval; /* default argument value */ | 83 | ARG_INT, //getbsz |
84 | ARG_INT + FL_NORESULT + FL_USRARG, //setbsz | ||
85 | ARG_U64 + FL_SCALE512, //getsz | ||
86 | ARG_ULONG, //getsize | ||
87 | ARG_U64, //getsize64 | ||
88 | ARG_NONE + FL_NORESULT, //flushbufs | ||
89 | ARG_NONE + FL_NORESULT, //rereadpt | ||
55 | }; | 90 | }; |
56 | 91 | ||
57 | static const struct bdc bdcommands[] = { | 92 | static unsigned find_cmd(const char *s) |
58 | { | ||
59 | .ioc = BLKROSET, | ||
60 | .name = "setro", | ||
61 | .flags = ARG_INT + FL_NORESULT, | ||
62 | .argval = 1, | ||
63 | },{ | ||
64 | .ioc = BLKROSET, | ||
65 | .name = "setrw", | ||
66 | .flags = ARG_INT + FL_NORESULT, | ||
67 | .argval = 0, | ||
68 | },{ | ||
69 | .ioc = BLKROGET, | ||
70 | .name = "getro", | ||
71 | .flags = ARG_INT, | ||
72 | .argval = -1, | ||
73 | },{ | ||
74 | .ioc = BLKSSZGET, | ||
75 | .name = "getss", | ||
76 | .flags = ARG_INT, | ||
77 | .argval = -1, | ||
78 | },{ | ||
79 | .ioc = BLKBSZGET, | ||
80 | .name = "getbsz", | ||
81 | .flags = ARG_INT, | ||
82 | .argval = -1, | ||
83 | },{ | ||
84 | .ioc = BLKBSZSET, | ||
85 | .name = "setbsz", | ||
86 | .flags = ARG_INT + FL_NORESULT + FL_USRARG, | ||
87 | .argval = 0, | ||
88 | },{ | ||
89 | .ioc = BLKGETSIZE64, | ||
90 | .name = "getsz", | ||
91 | .flags = ARG_U64 + FL_SCALE512, | ||
92 | .argval = -1, | ||
93 | },{ | ||
94 | .ioc = BLKGETSIZE, | ||
95 | .name = "getsize", | ||
96 | .flags = ARG_ULONG, | ||
97 | .argval = -1, | ||
98 | },{ | ||
99 | .ioc = BLKGETSIZE64, | ||
100 | .name = "getsize64", | ||
101 | .flags = ARG_U64, | ||
102 | .argval = -1, | ||
103 | },{ | ||
104 | .ioc = BLKFLSBUF, | ||
105 | .name = "flushbufs", | ||
106 | .flags = ARG_NONE + FL_NORESULT, | ||
107 | .argval = 0, | ||
108 | },{ | ||
109 | .ioc = BLKRRPART, | ||
110 | .name = "rereadpt", | ||
111 | .flags = ARG_NONE + FL_NORESULT, | ||
112 | .argval = 0, | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | static const struct bdc *find_cmd(const char *s) | ||
117 | { | 93 | { |
118 | const struct bdc *bdcmd = bdcommands; | ||
119 | if (s[0] == '-' && s[1] == '-') { | 94 | if (s[0] == '-' && s[1] == '-') { |
120 | s += 2; | 95 | int n = index_in_strings(bdcmd_names, s + 2); |
121 | do { | 96 | if (n >= 0) |
122 | if (strcmp(s, bdcmd->name) == 0) | 97 | return n; |
123 | return bdcmd; | ||
124 | bdcmd++; | ||
125 | } while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands)); | ||
126 | } | 98 | } |
127 | bb_show_usage(); | 99 | bb_show_usage(); |
128 | } | 100 | } |
@@ -130,7 +102,8 @@ static const struct bdc *find_cmd(const char *s) | |||
130 | int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 102 | int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
131 | int blockdev_main(int argc UNUSED_PARAM, char **argv) | 103 | int blockdev_main(int argc UNUSED_PARAM, char **argv) |
132 | { | 104 | { |
133 | const struct bdc *bdcmd; | 105 | unsigned bdcmd; |
106 | unsigned flags; | ||
134 | int fd; | 107 | int fd; |
135 | uint64_t u64; | 108 | uint64_t u64; |
136 | union { | 109 | union { |
@@ -144,10 +117,13 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv) | |||
144 | bb_show_usage(); | 117 | bb_show_usage(); |
145 | 118 | ||
146 | bdcmd = find_cmd(*argv); | 119 | bdcmd = find_cmd(*argv); |
147 | 120 | /* setrw translates to BLKROSET(0), most other ioctls don't care... */ | |
148 | u64 = (int)bdcmd->argval; | 121 | /* ...setro will do BLKROSET(1) */ |
149 | if (bdcmd->flags & FL_USRARG) | 122 | u64 = (bdcmd == CMD_SETRO); |
123 | if (bdcmd == CMD_SETBSZ) { | ||
124 | /* ...setbsz is BLKBSZSET(bytes) */ | ||
150 | u64 = xatoi_positive(*++argv); | 125 | u64 = xatoi_positive(*++argv); |
126 | } | ||
151 | 127 | ||
152 | argv++; | 128 | argv++; |
153 | if (!argv[0] || argv[1]) | 129 | if (!argv[0] || argv[1]) |
@@ -155,6 +131,7 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv) | |||
155 | fd = xopen(argv[0], O_RDONLY); | 131 | fd = xopen(argv[0], O_RDONLY); |
156 | 132 | ||
157 | ioctl_val_on_stack.u64 = u64; | 133 | ioctl_val_on_stack.u64 = u64; |
134 | flags = bdcmd_flags[bdcmd]; | ||
158 | #if BB_BIG_ENDIAN | 135 | #if BB_BIG_ENDIAN |
159 | /* Store data properly wrt data size. | 136 | /* Store data properly wrt data size. |
160 | * (1) It's no-op for little-endian. | 137 | * (1) It's no-op for little-endian. |
@@ -162,7 +139,7 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv) | |||
162 | * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT. | 139 | * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT. |
163 | * Thus, we don't need to handle ARG_ULONG. | 140 | * Thus, we don't need to handle ARG_ULONG. |
164 | */ | 141 | */ |
165 | switch (bdcmd->flags & ARG_MASK) { | 142 | switch (flags & ARG_MASK) { |
166 | case ARG_INT: | 143 | case ARG_INT: |
167 | ioctl_val_on_stack.i = (int)u64; | 144 | ioctl_val_on_stack.i = (int)u64; |
168 | break; | 145 | break; |
@@ -174,17 +151,17 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv) | |||
174 | } | 151 | } |
175 | #endif | 152 | #endif |
176 | 153 | ||
177 | if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1) | 154 | if (ioctl(fd, bdcmd_ioctl[bdcmd], &ioctl_val_on_stack.u64) == -1) |
178 | bb_simple_perror_msg_and_die(*argv); | 155 | bb_simple_perror_msg_and_die(*argv); |
179 | 156 | ||
180 | /* Fetch it into register(s) */ | 157 | /* Fetch it into register(s) */ |
181 | u64 = ioctl_val_on_stack.u64; | 158 | u64 = ioctl_val_on_stack.u64; |
182 | 159 | ||
183 | if (bdcmd->flags & FL_SCALE512) | 160 | if (flags & FL_SCALE512) |
184 | u64 >>= 9; | 161 | u64 >>= 9; |
185 | 162 | ||
186 | /* Zero- or one-extend the value if needed, then print */ | 163 | /* Zero- or one-extend the value if needed, then print */ |
187 | switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) { | 164 | switch (flags & (ARG_MASK+FL_NORESULT)) { |
188 | case ARG_INT: | 165 | case ARG_INT: |
189 | /* Smaller code when we use long long | 166 | /* Smaller code when we use long long |
190 | * (gcc tail-merges printf call) | 167 | * (gcc tail-merges printf call) |