From 66a781acb9c3a78f3063d1e691a1b18a5f9f68ab Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Sep 2015 03:27:08 +0200 Subject: ash: add tests adapted from hush glob tests. glob2.tests currently fails Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-glob/glob1.right | 2 ++ shell/ash_test/ash-glob/glob1.tests | 2 ++ shell/ash_test/ash-glob/glob2.right | 18 ++++++++++++++++++ shell/ash_test/ash-glob/glob2.tests | 27 +++++++++++++++++++++++++++ shell/ash_test/ash-glob/glob_and_assign.right | 6 ++++++ shell/ash_test/ash-glob/glob_and_assign.tests | 10 ++++++++++ shell/ash_test/ash-glob/glob_redir.right | 2 ++ shell/ash_test/ash-glob/glob_redir.tests | 9 +++++++++ 8 files changed, 76 insertions(+) create mode 100644 shell/ash_test/ash-glob/glob1.right create mode 100755 shell/ash_test/ash-glob/glob1.tests create mode 100644 shell/ash_test/ash-glob/glob2.right create mode 100755 shell/ash_test/ash-glob/glob2.tests create mode 100644 shell/ash_test/ash-glob/glob_and_assign.right create mode 100755 shell/ash_test/ash-glob/glob_and_assign.tests create mode 100644 shell/ash_test/ash-glob/glob_redir.right create mode 100755 shell/ash_test/ash-glob/glob_redir.tests (limited to 'shell') diff --git a/shell/ash_test/ash-glob/glob1.right b/shell/ash_test/ash-glob/glob1.right new file mode 100644 index 000000000..f29ab4e65 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.right @@ -0,0 +1,2 @@ +glob1.tests +glob1.tests diff --git a/shell/ash_test/ash-glob/glob1.tests b/shell/ash_test/ash-glob/glob1.tests new file mode 100755 index 000000000..f980ce064 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.tests @@ -0,0 +1,2 @@ +echo *glob1?t[e]sts* +echo "glob1"?'t'[e]s* diff --git a/shell/ash_test/ash-glob/glob2.right b/shell/ash_test/ash-glob/glob2.right new file mode 100644 index 000000000..7a70c2263 --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.right @@ -0,0 +1,18 @@ +Expected Actual +Z\* : Z\* +Z* : Z* +Z\f : Z\f +Z\* : Z\* + +Z\z : Z\z +Zz : Zz +Z\z : Z\z +Z\z : Z\z + +Z\ : Z\ +Z\ : Z\ + +Z\f Zf : Z\f Zf +Z\f Zf : Z\f Zf + +Done: 0 diff --git a/shell/ash_test/ash-glob/glob2.tests b/shell/ash_test/ash-glob/glob2.tests new file mode 100755 index 000000000..00618b9db --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.tests @@ -0,0 +1,27 @@ +# This test demonstrates that in unquoted $v, backslashes expand by this rule: +# \z -> \\\z; \ -> \\ (for any z, special or not), +# and subsequently globbing converts \\ to \ and treats \z as literal z +# even if it is a special char. + +>'Zf' +>'Z\f' + echo 'Expected' 'Actual' +v='\*'; echo 'Z\* :' Z$v # ash is buggy here: prints 'Z\f' + echo 'Z* :' Z\* + echo 'Z\f :' Z\\* + echo 'Z\* :' Z\\\* # NB! only this matches Z$v output +echo +v='\z'; echo 'Z\z :' Z$v + echo 'Zz :' Z\z + echo 'Z\z :' Z\\z + echo 'Z\z :' Z\\\z +echo +v='\'; echo 'Z\ :' Z$v + echo 'Z\ :' Z\\ +echo +v='*'; echo 'Z\f Zf :' Z$v + echo 'Z\f Zf :' Z* +echo + +rm 'Z\f' 'Zf' +echo Done: $? diff --git a/shell/ash_test/ash-glob/glob_and_assign.right b/shell/ash_test/ash-glob/glob_and_assign.right new file mode 100644 index 000000000..d46e44363 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.right @@ -0,0 +1,6 @@ +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +*.tmp +ZVAR=z.tmp z.tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp diff --git a/shell/ash_test/ash-glob/glob_and_assign.tests b/shell/ash_test/ash-glob/glob_and_assign.tests new file mode 100755 index 000000000..0b158f20f --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.tests @@ -0,0 +1,10 @@ +>ZVAR=z.tmp +>z.tmp +ZVAR=*.tmp echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +ZVAR=*.tmp /bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +ZVAR=*.tmp +echo "$ZVAR" +echo $ZVAR +echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +/bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +rm ZVAR=z.tmp z.tmp diff --git a/shell/ash_test/ash-glob/glob_redir.right b/shell/ash_test/ash-glob/glob_redir.right new file mode 100644 index 000000000..fbd0309b0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.right @@ -0,0 +1,2 @@ +z.tmp: +?.tmp: TEST diff --git a/shell/ash_test/ash-glob/glob_redir.tests b/shell/ash_test/ash-glob/glob_redir.tests new file mode 100755 index 000000000..621d12017 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.tests @@ -0,0 +1,9 @@ +# Redirections are not globbed. +# bash: +# if run as "sh", they are not globbed, but +# if run as "bash", they are! +>z.tmp +echo TEST >?.tmp +echo 'z.tmp:' `cat 'z.tmp'` +echo '?.tmp:' `cat '?.tmp'` +rm 'z.tmp' '?.tmp' -- cgit v1.2.3-55-g6feb From 26c423d9a8d455af59cbce70ff932c95842a2ba1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Sep 2015 03:33:02 +0200 Subject: ash,hush: add a test which fails for ash since commit 549deab Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-glob/glob3.right | 2 ++ shell/ash_test/ash-glob/glob3.tests | 2 ++ shell/hush_test/hush-glob/glob3.right | 2 ++ shell/hush_test/hush-glob/glob3.tests | 2 ++ 4 files changed, 8 insertions(+) create mode 100644 shell/ash_test/ash-glob/glob3.right create mode 100755 shell/ash_test/ash-glob/glob3.tests create mode 100644 shell/hush_test/hush-glob/glob3.right create mode 100755 shell/hush_test/hush-glob/glob3.tests (limited to 'shell') diff --git a/shell/ash_test/ash-glob/glob3.right b/shell/ash_test/ash-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.right @@ -0,0 +1,2 @@ +glob3.tests +./glob3.tests diff --git a/shell/ash_test/ash-glob/glob3.tests b/shell/ash_test/ash-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.tests @@ -0,0 +1,2 @@ +echo "glob3.test"* +echo "./glob3.test"* diff --git a/shell/hush_test/hush-glob/glob3.right b/shell/hush_test/hush-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.right @@ -0,0 +1,2 @@ +glob3.tests +./glob3.tests diff --git a/shell/hush_test/hush-glob/glob3.tests b/shell/hush_test/hush-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.tests @@ -0,0 +1,2 @@ +echo "glob3.test"* +echo "./glob3.test"* -- cgit v1.2.3-55-g6feb From b5be13ccd9ce2120468a381a5475955013c0f049 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Sep 2015 06:22:10 +0200 Subject: hush: fix a nommu bug where a part of function body is lost if run in a pipe Signed-off-by: Denys Vlasenko --- shell/hush.c | 35 ++++++++++++++++++++++++---------- shell/hush_test/hush-misc/nommu3.right | 2 ++ shell/hush_test/hush-misc/nommu3.tests | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 shell/hush_test/hush-misc/nommu3.right create mode 100755 shell/hush_test/hush-misc/nommu3.tests (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 3ca04494c..752080a64 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -3161,11 +3161,29 @@ static int reserved_word(o_string *word, struct parse_context *ctx) old->command->group = ctx->list_head; old->command->cmd_type = CMD_NORMAL; # if !BB_MMU - o_addstr(&old->as_string, ctx->as_string.data); - o_free_unsafe(&ctx->as_string); - old->command->group_as_string = xstrdup(old->as_string.data); - debug_printf_parse("pop, remembering as:'%s'\n", - old->command->group_as_string); + /* At this point, the compound command's string is in + * ctx->as_string... except for the leading keyword! + * Consider this example: "echo a | if true; then echo a; fi" + * ctx->as_string will contain "true; then echo a; fi", + * with "if " remaining in old->as_string! + */ + { + char *str; + int len = old->as_string.length; + /* Concatenate halves */ + o_addstr(&old->as_string, ctx->as_string.data); + o_free_unsafe(&ctx->as_string); + /* Find where leading keyword starts in first half */ + str = old->as_string.data + len; + if (str > old->as_string.data) + str--; /* skip whitespace after keyword */ + while (str > old->as_string.data && isalpha(str[-1])) + str--; + /* Ugh, we're done with this horrid hack */ + old->command->group_as_string = xstrdup(str); + debug_printf_parse("pop, remembering as:'%s'\n", + old->command->group_as_string); + } # endif *ctx = *old; /* physical copy */ free(old); @@ -4248,7 +4266,7 @@ static struct pipe *parse_stream(char **pstring, pi = NULL; } #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4399,7 +4417,7 @@ static struct pipe *parse_stream(char **pstring, ) { o_free(&dest); #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4639,9 +4657,6 @@ static struct pipe *parse_stream(char **pstring, * with redirect_opt_num(), but bash doesn't do it. * "echo foo 2| cat" yields "foo 2". */ done_command(&ctx); -#if !BB_MMU - o_reset_to_empty_unquoted(&ctx.as_string); -#endif } goto new_cmd; case '(': diff --git a/shell/hush_test/hush-misc/nommu3.right b/shell/hush_test/hush-misc/nommu3.right new file mode 100644 index 000000000..da1534bef --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.right @@ -0,0 +1,2 @@ +Ok +0 diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests new file mode 100755 index 000000000..0aca67a67 --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.tests @@ -0,0 +1,15 @@ +#!/bin/sh + +func() +{ + while read p; do echo "$p"; done +} + +pipe_to_func() +{ + # We had a NOMMU bug which caused "echo Ok |" part ot be lost + echo Ok | func +} + +pipe_to_func | cat +echo $? -- cgit v1.2.3-55-g6feb From ca25af9b06b0c3ded77ac70087227896b34003c4 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 4 Sep 2015 10:32:41 +0100 Subject: ash: fix slash treatment in expmeta Commit 549deab caused this sequence of commands: mkdir foo cd foo touch a b echo "./"* to return './*' instead of the expected './a ./b'. The problem was caused by the backport of commit 880d952 from dash. In dash the issue was fixed by two further commits by Herbert Xu: [EXPAND] Fixed non-leading slash treatment in expmeta <36f0fa8> [EXPAND] Fix slash treatment in expmeta (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Apply these fixes to BusyBox ash, thus causing the new test glob3.tests to succeed. function old new delta expmeta 469 528 +59 Reported-by: Aaro Koskinen Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index f6190c3e2..42c91257e 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6992,10 +6992,11 @@ expmeta(char *expdir, char *enddir, char *name) struct dirent *dp; int atend; int matchdot; + int esc; metaflag = 0; start = name; - for (p = name; *p; p++) { + for (p = name; esc = 0, *p; p += esc + 1) { if (*p == '*' || *p == '?') metaflag = 1; else if (*p == '[') { @@ -7012,15 +7013,16 @@ expmeta(char *expdir, char *enddir, char *name) break; } } - } else if (*p == '\\') - p++; - else if (*p == '/') { - if (metaflag) - goto out; - start = p + 1; + } else { + if (*p == '\\') + esc++; + if (p[esc] == '/') { + if (metaflag) + break; + start = p + esc + 1; + } } } - out: if (metaflag == 0) { /* we've reached the end of the file name */ if (enddir != expdir) metaflag++; @@ -7060,7 +7062,8 @@ expmeta(char *expdir, char *enddir, char *name) atend = 1; } else { atend = 0; - *endname++ = '\0'; + *endname = '\0'; + endname += esc + 1; } matchdot = 0; p = start; @@ -7085,7 +7088,7 @@ expmeta(char *expdir, char *enddir, char *name) } closedir(dirp); if (!atend) - endname[-1] = '/'; + endname[-esc - 1] = esc ? '\\' : '/'; } static struct strlist * -- cgit v1.2.3-55-g6feb From 9c5410023a9d1920c336ed4d9ceaad586ce43328 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 15:44:36 +0200 Subject: ash: a bunch of trivial simplifications Also, in a few places made code more reliable wrt large sizeof(int) and sizeof(arith_t).. function old new delta sprint_status48 - 143 +143 newline_and_flush - 56 +56 showjob 365 382 +17 parse_command 1440 1443 +3 cmdputs 334 332 -2 cmdloop 434 429 -5 showjobs 70 64 -6 fg_bgcmd 296 290 -6 ash_vmsg 159 153 -6 ash_main 1487 1481 -6 jobscmd 94 82 -12 getoptscmd 687 632 -55 outcslow 56 - -56 sprint_status 156 - -156 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 2/8 up/down: 219/-310) Total: -91 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 72 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 35 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 42c91257e..b34dcc149 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -537,11 +537,12 @@ flush_stdout_stderr(void) INT_ON; } +/* Was called outcslow(c,FILE*), but c was always '\n' */ static void -outcslow(int c, FILE *dest) +newline_and_flush(FILE *dest) { INT_OFF; - putc(c, dest); + putc('\n', dest); fflush(dest); INT_ON; } @@ -1202,7 +1203,7 @@ ash_vmsg(const char *msg, va_list ap) fprintf(stderr, "line %d: ", startlinno); } vfprintf(stderr, msg, ap); - outcslow('\n', stderr); + newline_and_flush(stderr); } /* @@ -3336,6 +3337,7 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) #define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */ #define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */ #define SHOW_CHANGED 0x04 /* only jobs whose state has changed */ +#define SHOW_STDERR 0x08 /* print to stderr (else stdout) */ /* * A job structure contains information about a job. A job is either a @@ -3850,7 +3852,7 @@ showpipe(struct job *jp /*, FILE *out*/) psend = jp->ps + jp->nprocs; for (ps = jp->ps + 1; ps < psend; ps++) printf(" | %s", ps->ps_cmd); - outcslow('\n', stdout); + newline_and_flush(stdout); flush_stdout_stderr(); } @@ -3910,7 +3912,7 @@ fg_bgcmd(int argc UNUSED_PARAM, char **argv) #endif static int -sprint_status(char *s, int status, int sigonly) +sprint_status48(char *s, int status, int sigonly) { int col; int st; @@ -3935,14 +3937,12 @@ sprint_status(char *s, int status, int sigonly) //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata col = fmtstr(s, 32, strsignal(st)); if (WCOREDUMP(status)) { - col += fmtstr(s + col, 16, " (core dumped)"); + strcpy(s + col, " (core dumped)"); + col += sizeof(" (core dumped)")-1; } } else if (!sigonly) { st = WEXITSTATUS(status); - if (st) - col = fmtstr(s, 16, "Done(%d)", st); - else - col = fmtstr(s, 16, "Done"); + col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st); } out: return col; @@ -4031,7 +4031,7 @@ dowait(int wait_flags, struct job *job) char s[48 + 1]; int len; - len = sprint_status(s, status, 1); + len = sprint_status48(s, status, 1); if (len) { s[len] = '\n'; s[len + 1] = '\0'; @@ -4052,13 +4052,14 @@ blocking_wait_with_raise_on_sig(void) #if JOBS static void -showjob(FILE *out, struct job *jp, int mode) +showjob(struct job *jp, int mode) { struct procstat *ps; struct procstat *psend; int col; int indent_col; - char s[80]; + char s[16 + 16 + 48]; + FILE *out = (mode & SHOW_STDERR ? stderr : stdout); ps = jp->ps; @@ -4088,7 +4089,7 @@ showjob(FILE *out, struct job *jp, int mode) int status = psend[-1].ps_status; if (jp->state == JOBSTOPPED) status = jp->stopstatus; - col += sprint_status(s + col, status, 0); + col += sprint_status48(s + col, status, 0); } /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ @@ -4115,7 +4116,7 @@ showjob(FILE *out, struct job *jp, int mode) ps->ps_cmd ); } while (++ps != psend); - outcslow('\n', out); + newline_and_flush(out); jp->changed = 0; @@ -4130,7 +4131,7 @@ showjob(FILE *out, struct job *jp, int mode) * statuses have changed since the last call to showjobs. */ static void -showjobs(FILE *out, int mode) +showjobs(int mode) { struct job *jp; @@ -4142,7 +4143,7 @@ showjobs(FILE *out, int mode) for (jp = curjob; jp; jp = jp->prev_job) { if (!(mode & SHOW_CHANGED) || jp->changed) { - showjob(out, jp, mode); + showjob(jp, mode); } } } @@ -4163,10 +4164,10 @@ jobscmd(int argc UNUSED_PARAM, char **argv) argv = argptr; if (*argv) { do - showjob(stdout, getjob(*argv, 0), mode); + showjob(getjob(*argv, 0), mode); while (*++argv); } else { - showjobs(stdout, mode); + showjobs(mode); } return 0; @@ -5572,8 +5573,8 @@ cvtnum(arith_t num) { int len; - expdest = makestrspace(32, expdest); - len = fmtstr(expdest, 32, ARITH_FMT, num); + expdest = makestrspace(sizeof(arith_t)*3 + 2, expdest); + len = fmtstr(expdest, sizeof(arith_t)*3 + 2, ARITH_FMT, num); STADJUST(len, expdest); return len; } @@ -10352,9 +10353,11 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt char c = '?'; int done = 0; int err = 0; - char s[12]; + char sbuf[2]; char **optnext; + sbuf[1] = '\0'; + if (*param_optind < 1) return 1; optnext = optfirst + *param_optind - 1; @@ -10381,9 +10384,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt for (q = optstr; *q != c;) { if (*q == '\0') { if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe("OPTARG", sbuf, 0); } else { fprintf(stderr, "Illegal option -%c\n", c); unsetvar("OPTARG"); @@ -10398,9 +10401,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt if (*++q == ':') { if (*p == '\0' && (p = *optnext) == NULL) { if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe("OPTARG", sbuf, 0); c = ':'; } else { fprintf(stderr, "No arg for -%c option\n", c); @@ -10419,11 +10422,10 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt out: *optoff = p ? p - *(optnext - 1) : -1; *param_optind = optnext - optfirst + 1; - fmtstr(s, sizeof(s), "%d", *param_optind); - err |= setvarsafe("OPTIND", s, VNOFUNC); - s[0] = c; - s[1] = '\0'; - err |= setvarsafe(optvar, s, 0); + err |= setvarsafe("OPTIND", itoa(*param_optind), VNOFUNC); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe(optvar, sbuf, 0); if (err) { *param_optind = 1; *optoff = -1; @@ -12119,7 +12121,7 @@ cmdloop(int top) setstackmark(&smark); #if JOBS if (doing_jobctl) - showjobs(stderr, SHOW_CHANGED); + showjobs(SHOW_CHANGED|SHOW_STDERR); #endif inter = 0; if (iflag && top) { @@ -13143,7 +13145,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) exitshell(); } if (e == EXINT) { - outcslow('\n', stderr); + newline_and_flush(stderr); } popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 6283f9828320ef5e0be0b060b7f26522b529ed42 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 16:56:20 +0200 Subject: hush: fix umask: umask(022) was setting umask(755) Based on the patch by Rich Felker function old new delta builtin_umask 121 161 +40 umaskcmd 318 279 -39 Signed-off-by: Denys Vlasenko --- shell/ash.c | 36 ++++++++++++++---------------------- shell/hush.c | 10 +++++++--- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index b34dcc149..2669157bc 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12814,7 +12814,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } static int FAST_FUNC -umaskcmd(int argc UNUSED_PARAM, char **argv) +umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { static const char permuser[3] ALIGN1 = "ugo"; static const char permmode[3] ALIGN1 = "rwx"; @@ -12824,9 +12824,6 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) S_IROTH, S_IWOTH, S_IXOTH }; - /* TODO: use bb_parse_mode() instead */ - - char *ap; mode_t mask; int i; int symbolic_mode = 0; @@ -12840,8 +12837,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) umask(mask); INT_ON; - ap = *argptr; - if (ap == NULL) { + if (*argptr == NULL) { if (symbolic_mode) { char buf[18]; char *p = buf; @@ -12858,27 +12854,23 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) } *p++ = ','; } - *--p = 0; + *--p = '\0'; puts(buf); } else { out1fmt("%.4o\n", mask); } } else { - if (isdigit((unsigned char) *ap)) { - mask = 0; - do { - if (*ap >= '8' || *ap < '0') - ash_msg_and_raise_error(msg_illnum, argv[1]); - mask = (mask << 3) + (*ap - '0'); - } while (*++ap != '\0'); - umask(mask); - } else { - mask = ~mask & 0777; - if (!bb_parse_mode(ap, &mask)) { - ash_msg_and_raise_error("illegal mode: %s", ap); - } - umask(~mask & 0777); - } + char *modestr = *argptr; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(modestr[0])) + mask ^= 0777; + if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { + ash_msg_and_raise_error("illegal mode: %s", modestr); + } + if (!isdigit(modestr[0])) + mask ^= 0777; + umask(mask); } return 0; } diff --git a/shell/hush.c b/shell/hush.c index 752080a64..8b8d5fc8b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8970,10 +8970,14 @@ static int FAST_FUNC builtin_umask(char **argv) if (argv[0]) { mode_t old_mask = mask; - mask ^= 0777; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(argv[0][0])) + mask ^= 0777; rc = bb_parse_mode(argv[0], &mask); - mask ^= 0777; - if (rc == 0) { + if (!isdigit(argv[0][0])) + mask ^= 0777; + if (rc == 0 || (unsigned)mask > 0777) { mask = old_mask; /* bash messages: * bash: umask: 'q': invalid symbolic mode operator -- cgit v1.2.3-55-g6feb From c1e2e005b4e99070f58a3545bad54ef41a634ad1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 17:32:56 +0200 Subject: ash: shrink "umask -S" code function old new delta umaskcmd 279 286 +7 static.permmode 3 - -3 static.permmask 18 - -18 Signed-off-by: Denys Vlasenko --- shell/ash.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 2669157bc..80dfc1d6a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12816,16 +12816,9 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) static int FAST_FUNC umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { - static const char permuser[3] ALIGN1 = "ugo"; - static const char permmode[3] ALIGN1 = "rwx"; - static const short permmask[] ALIGN2 = { - S_IRUSR, S_IWUSR, S_IXUSR, - S_IRGRP, S_IWGRP, S_IXGRP, - S_IROTH, S_IWOTH, S_IXOTH - }; + static const char permuser[3] ALIGN1 = "ogu"; mode_t mask; - int i; int symbolic_mode = 0; while (nextopt("S") != '\0') { @@ -12839,22 +12832,26 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) if (*argptr == NULL) { if (symbolic_mode) { - char buf[18]; + char buf[sizeof("u=rwx,g=rwx,o=rwx")]; char *p = buf; + int i; - for (i = 0; i < 3; i++) { - int j; + i = 2; + for (;;) { + unsigned bits; *p++ = permuser[i]; *p++ = '='; - for (j = 0; j < 3; j++) { - if ((mask & permmask[3 * i + j]) == 0) { - *p++ = permmode[j]; - } - } + /* mask is 0..0uuugggooo. i=2 selects uuu bits */ + bits = (mask >> (i*3)); + if (!(bits & 4)) *p++ = 'r'; + if (!(bits & 2)) *p++ = 'w'; + if (!(bits & 1)) *p++ = 'x'; + if (--i < 0) + break; *p++ = ','; } - *--p = '\0'; + *p = '\0'; puts(buf); } else { out1fmt("%.4o\n", mask); -- cgit v1.2.3-55-g6feb From 5711a2a4ad51ad203a2ed4ffc72593e83920b36a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 17:55:33 +0200 Subject: libbb: more compact API for bb_parse_mode() function old new delta make_device 2182 2188 +6 parse_command 1440 1443 +3 parse_params 1497 1499 +2 install_main 773 769 -4 mkdir_main 168 160 -8 getoptscmd 641 632 -9 builtin_umask 158 147 -11 bb_parse_mode 431 410 -21 umaskcmd 286 258 -28 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/6 up/down: 11/-81) Total: -70 bytes Signed-off-by: Denys Vlasenko --- coreutils/chmod.c | 4 ++-- coreutils/install.c | 2 +- coreutils/libcoreutils/getopt_mk_fifo_nod.c | 4 +++- coreutils/mkdir.c | 4 ++-- findutils/find.c | 3 ++- include/libbb.h | 3 ++- libbb/parse_mode.c | 16 +++++++--------- shell/ash.c | 3 ++- shell/hush.c | 7 ++++--- util-linux/mdev.c | 2 +- 10 files changed, 26 insertions(+), 22 deletions(-) (limited to 'shell') diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 5ee45b942..a21c6d501 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -69,9 +69,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void if (S_ISLNK(statbuf->st_mode)) return TRUE; } - newmode = statbuf->st_mode; - if (!bb_parse_mode((char *)param, &newmode)) + newmode = bb_parse_mode((char *)param, statbuf->st_mode); + if (newmode == (mode_t)-1) bb_error_msg_and_die("invalid mode '%s'", (char *)param); if (chmod(fileName, newmode) == 0) { diff --git a/coreutils/install.c b/coreutils/install.c index 73f9c70d5..8aa51cc34 100644 --- a/coreutils/install.c +++ b/coreutils/install.c @@ -159,7 +159,7 @@ int install_main(int argc, char **argv) } mode = 0755; /* GNU coreutils 6.10 compat */ if (opts & OPT_MODE) - bb_parse_mode(mode_str, &mode); + mode = bb_parse_mode(mode_str, mode); uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c index 222717149..47375ff91 100644 --- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c @@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv) int opt; opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - if (bb_parse_mode(smode, &mode)) + mode = bb_parse_mode(smode, mode); + if (mode != (mode_t)-1) /* if mode is valid */ + /* make future mknod/mkfifo set mode bits exactly */ umask(0); } diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 864edfb0a..6f7b004dd 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c @@ -71,8 +71,8 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv) #endif opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - mode_t mmode = 0777; - if (!bb_parse_mode(smode, &mmode)) { + mode_t mmode = bb_parse_mode(smode, 0777); + if (mmode == (mode_t)-1) { bb_error_msg_and_die("invalid mode '%s'", smode); } mode = mmode; diff --git a/findutils/find.c b/findutils/find.c index ced8922e7..f72cad7d1 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -1261,7 +1261,8 @@ static action*** parse_params(char **argv) ap->perm_char = arg1[0]; arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1)); /*ap->perm_mask = 0; - ALLOC_ACTION did it */ - if (!bb_parse_mode(arg1, &ap->perm_mask)) + ap->perm_mask = bb_parse_mode(arg1, ap->perm_mask); + if (ap->perm_mask == (mode_t)-1) bb_error_msg_and_die("invalid mode '%s'", arg1); } #endif diff --git a/include/libbb.h b/include/libbb.h index 543214ea4..d79843a2d 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1251,7 +1251,8 @@ char *bb_ask_stdin(const char * prompt) FAST_FUNC; char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; int bb_ask_confirmation(void) FAST_FUNC; -int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; +/* Returns -1 if input is invalid. current_mode is a base for e.g. "u+rw" */ +int bb_parse_mode(const char* s, unsigned cur_mode) FAST_FUNC; /* * Config file parser diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c index 5a4e1c579..bddd39bca 100644 --- a/libbb/parse_mode.c +++ b/libbb/parse_mode.c @@ -15,7 +15,7 @@ #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) -int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) +int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) { static const mode_t who_mask[] = { S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ @@ -46,13 +46,12 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) tmp = strtoul(s, &e, 8); if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ - return 0; + return -1; } - *current_mode = tmp; - return 1; + return tmp; } - new_mode = *current_mode; + new_mode = current_mode; /* Note: we allow empty clauses, and hence empty modes. * We treat an empty mode as no change to perms. */ @@ -71,7 +70,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) if (*p == *s) { wholist |= who_mask[(int)(p-who_chars)]; if (!*++s) { - return 0; + return -1; } goto WHO_LIST; } @@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) do { /* Process action list. */ if ((*s != '+') && (*s != '-')) { if (*s != '=') { - return 0; + return -1; } /* Since op is '=', clear all bits corresponding to the * wholist, or all file bits if wholist is empty. */ @@ -145,6 +144,5 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) } while (*s && (*s != ',')); } - *current_mode = new_mode; - return 1; + return new_mode; } diff --git a/shell/ash.c b/shell/ash.c index 80dfc1d6a..ab8ec006f 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12862,7 +12862,8 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ if (!isdigit(modestr[0])) mask ^= 0777; - if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { + mask = bb_parse_mode(modestr, mask); + if ((unsigned)mask > 0777) { ash_msg_and_raise_error("illegal mode: %s", modestr); } if (!isdigit(modestr[0])) diff --git a/shell/hush.c b/shell/hush.c index 8b8d5fc8b..bccd9c1e9 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8965,6 +8965,7 @@ static int FAST_FUNC builtin_umask(char **argv) int rc; mode_t mask; + rc = 1; mask = umask(0); argv = skip_dash_dash(argv); if (argv[0]) { @@ -8974,19 +8975,19 @@ static int FAST_FUNC builtin_umask(char **argv) /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ if (!isdigit(argv[0][0])) mask ^= 0777; - rc = bb_parse_mode(argv[0], &mask); + mask = bb_parse_mode(argv[0], mask); if (!isdigit(argv[0][0])) mask ^= 0777; - if (rc == 0 || (unsigned)mask > 0777) { + if ((unsigned)mask > 0777) { mask = old_mask; /* bash messages: * bash: umask: 'q': invalid symbolic mode operator * bash: umask: 999: octal number out of range */ bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); + rc = 0; } } else { - rc = 1; /* Mimic bash */ printf("%04o\n", (unsigned) mask); /* fall through and restore mask which we set to 0 */ diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 662e8ab38..51781d597 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -406,7 +406,7 @@ static void parse_next_rule(void) } /* 3rd field: mode - device permissions */ - bb_parse_mode(tokens[2], &G.cur_rule.mode); + G.cur_rule.mode = bb_parse_mode(tokens[2], G.cur_rule.mode); /* 4th field (opt): ">|=alias" or "!" to not create the node */ val = tokens[3]; -- cgit v1.2.3-55-g6feb From ec046f74a31e4315f4546ec5602f56e7d467082d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 17:57:53 +0200 Subject: ash: use a more typical form of "print four octal digits" format Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index ab8ec006f..b835415b5 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12854,7 +12854,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) *p = '\0'; puts(buf); } else { - out1fmt("%.4o\n", mask); + out1fmt("%04o\n", mask); } } else { char *modestr = *argptr; -- cgit v1.2.3-55-g6feb From d60752f8c9be5689a249ad518deb38061d4bc45e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Oct 2015 22:42:45 +0200 Subject: build system: -fno-builtin-printf Benefits are: drops reference to out-of-line putchar(), fixes a few cases of failed string merge. function old new delta i2cdump_main 1488 1502 +14 sha256_process_block64 423 433 +10 sendmail_main 1183 1185 +2 list_table 1114 1116 +2 i2cdetect_main 1235 1237 +2 fdisk_main 2852 2854 +2 builtin_type 119 121 +2 unicode_conv_to_printable2 325 324 -1 scan_recursive 380 378 -2 mkfs_minix_main 2687 2684 -3 buffer_fill_and_print 178 169 -9 putchar 152 - -152 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 7/4 up/down: 34/-167) Total: -133 bytes text data bss dec hex filename 937788 932 17676 956396 e97ec busybox_old 937564 932 17676 956172 e970c busybox_unstripped Signed-off-by: Denys Vlasenko --- Makefile.flags | 3 ++ coreutils/uniq.c | 2 +- coreutils/who.c | 2 +- editors/diff.c | 4 +- editors/ed.c | 2 +- loginutils/add-remove-shell.c | 4 +- mailutils/mail.c | 2 +- mailutils/sendmail.c | 2 +- miscutils/hdparm.c | 58 +++++++++++++------------- miscutils/i2c_tools.c | 26 ++++++------ networking/arping.c | 2 +- networking/brctl.c | 4 +- printutils/lpd.c | 8 ++-- procps/iostat.c | 2 +- procps/powertop.c | 2 +- shell/ash.c | 2 +- shell/hush.c | 2 +- shell/shell_common.c | 2 +- util-linux/fdformat.c | 4 +- util-linux/fdisk.c | 94 +++++++++++++++++++++---------------------- util-linux/fdisk_gpt.c | 4 +- util-linux/fsck_minix.c | 16 ++++---- util-linux/getopt.c | 2 +- util-linux/ipcrm.c | 2 +- 24 files changed, 127 insertions(+), 124 deletions(-) (limited to 'shell') diff --git a/Makefile.flags b/Makefile.flags index 2bc83d1d9..b6cd32e42 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -56,6 +56,9 @@ CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): CFLAGS += $(call cc-option,-fno-unwind-tables,) CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) +# No automatic printf->puts,putchar conversions +# (try disabling this and comparing assembly, it's instructive) +CFLAGS += $(call cc-option,-fno-builtin-printf,) # FIXME: These warnings are at least partially to be concerned about and should # be fixed.. diff --git a/coreutils/uniq.c b/coreutils/uniq.c index 9208d34ec..e0133998a 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c @@ -112,7 +112,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) /* %7lu matches GNU coreutils 6.9 */ printf("%7lu ", dups + 1); } - printf("%s\n", old_line); + puts(old_line); } free(old_line); } diff --git a/coreutils/who.c b/coreutils/who.c index 8337212c9..f694d0c60 100644 --- a/coreutils/who.c +++ b/coreutils/who.c @@ -81,7 +81,7 @@ int who_main(int argc UNUSED_PARAM, char **argv) opt_complementary = "=0"; opt = getopt32(argv, do_users ? "" : "aH"); if (opt & 2) // -H - printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n"); + puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); setutxent(); while ((ut = getutxent()) != NULL) { diff --git a/editors/diff.c b/editors/diff.c index e0adcee59..a892cfdf2 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -433,7 +433,7 @@ static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch) for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { int c = fgetc(ft->ft_fp); if (c == EOF) { - printf("\n\\ No newline at end of file\n"); + puts("\n\\ No newline at end of file"); return; } ft->ft_pos++; @@ -692,7 +692,7 @@ static bool diff(FILE* fp[2], char *file[2]) continue; printf(",%d", (a < b) ? b - a + 1 : 0); } - printf(" @@\n"); + puts(" @@"); /* * Output changes in "unified" diff format--the old and new lines * are printed together. diff --git a/editors/ed.c b/editors/ed.c index f0e5e4d5d..a4c419099 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -206,7 +206,7 @@ static void doCommands(void) if (fileName) printf("\"%s\"\n", fileName); else - printf("No file name\n"); + puts("No file name"); break; } free(fileName); diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index e492b6e5a..9419ff5e7 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c @@ -100,7 +100,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) cpp++; } /* copy shell name from old to new file */ - printf("%s\n", line); + puts(line); next_line: free(line); } @@ -112,7 +112,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) char **cpp = argv; while (*cpp) { if (*cpp != dont_add) - printf("%s\n", *cpp); + puts(*cpp); cpp++; } } diff --git a/mailutils/mail.c b/mailutils/mail.c index 199f64407..a7e43c0d1 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c @@ -154,7 +154,7 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) // encode the buffer we just read in bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); if (fname) { - printf("%s\n", eol); + puts(eol); } else { src_buf += size; len -= size; diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 9455b4e7a..4355e4dc5 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -375,7 +375,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // N.B. we need to escape the leading dot regardless of // whether it is single or not character on the line if ('.' == s[0] /*&& '\0' == s[1] */) - printf("."); + bb_putchar('.'); // dump read line send_r_n(s); free(s); diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index f0e9c9d75..9c486e7aa 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -763,9 +763,9 @@ static void identify(uint16_t *val) ) { like_std = 5; if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) - printf("powers-up in standby; SET FEATURES subcmd spins-up.\n"); + puts("powers-up in standby; SET FEATURES subcmd spins-up."); if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) - printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n"); + puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); } /* output the model and serial numbers and the fw revision */ @@ -875,7 +875,7 @@ static void identify(uint16_t *val) if (min_std == 0xffff) min_std = like_std > 4 ? like_std - 3 : 1; - printf("Configuration:\n"); + puts("Configuration:"); /* more info from the general configuration word */ if ((eqpt != CDROM) && (like_std == 1)) { jj = val[GEN_CONFIG] >> 1; @@ -909,7 +909,7 @@ static void identify(uint16_t *val) mm = 0; bbbig = 0; if ((ll > 0x00FBFC10) && (!val[LCYLS])) - printf("\tCHS addressing not supported\n"); + puts("\tCHS addressing not supported"); else { jj = val[WHATS_VALID] & OK_W54_58; printf("\tLogical\t\tmax\tcurrent\n" @@ -980,7 +980,7 @@ static void identify(uint16_t *val) !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "", (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); } else - printf("no IORDY\n"); + puts("no IORDY"); if ((like_std == 1) && val[BUF_TYPE]) { printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE], @@ -1012,13 +1012,13 @@ static void identify(uint16_t *val) } printf("\tR/W multiple sector transfer: "); if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) - printf("not supported\n"); + puts("not supported"); else { printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER); if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID) printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER); else - printf("?\n"); + puts("?"); } if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { /* We print out elsewhere whether the APM feature is enabled or @@ -1040,7 +1040,7 @@ static void identify(uint16_t *val) } else { /* ATAPI */ if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) - printf("\tATA sw reset required\n"); + puts("\tATA sw reset required"); if (val[PKT_REL] || val[SVC_NBSY]) { printf("\tOverlap support:"); @@ -1056,7 +1056,7 @@ static void identify(uint16_t *val) /* DMA stuff. Check that only one DMA mode is selected. */ printf("\tDMA: "); if (!(val[CAPAB_0] & DMA_SUP)) - printf("not supported\n"); + puts("not supported"); else { if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8); @@ -1079,7 +1079,7 @@ static void identify(uint16_t *val) bb_putchar('\n'); if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) - printf("\t\tInterleaved DMA support\n"); + puts("\t\tInterleaved DMA support"); if ((val[WHATS_VALID] & OK_W64_70) && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM]) @@ -1121,8 +1121,8 @@ static void identify(uint16_t *val) } if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { - printf("Commands/features:\n" - "\tEnabled\tSupported:\n"); + puts("Commands/features:\n" + "\tEnabled\tSupported:"); jj = val[CMDS_SUPP_0]; kk = val[CMDS_EN_0]; for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { @@ -1150,7 +1150,7 @@ static void identify(uint16_t *val) if ((eqpt != CDROM) && (like_std > 3) && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]) ) { - printf("Security:\n"); + puts("Security:"); if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) printf("\tMaster password revision code = %u\n", val[PSWD_CODE]); jj = val[SECU_STATUS]; @@ -1366,7 +1366,7 @@ static NOINLINE void dump_identity(const struct hd_driveid *id) } } #endif /* __NEW_HD_DRIVE_ID */ - printf("\n\n * current active mode\n\n"); + puts("\n\n * current active mode\n"); } #endif @@ -1507,7 +1507,7 @@ static void bus_state_value(unsigned value) else if (value == BUSSTATE_OFF) on_off(0); else if (value == BUSSTATE_TRISTATE) - printf(" (tristate)\n"); + puts(" (tristate)"); else printf(" (unknown: %u)\n", value); } @@ -1531,7 +1531,7 @@ static void interpret_standby(uint8_t standby) printf("vendor-specific"); if (standby == 254) printf("reserved"); - printf(")\n"); + puts(")"); } static const uint8_t xfermode_val[] ALIGN1 = { @@ -1582,7 +1582,7 @@ static void interpret_xfermode(unsigned xfermode) printf("UltraDMA mode%u", xfermode - 64); else printf("unknown"); - printf(")\n"); + puts(")"); } #endif /* HDIO_DRIVE_CMD */ @@ -1633,7 +1633,7 @@ static void process_dev(char *devname) if (noisy_piomode) { printf(" attempting to "); if (piomode == 255) - printf("auto-tune PIO mode\n"); + puts("auto-tune PIO mode"); else if (piomode < 100) printf("set PIO mode to %d\n", piomode); else if (piomode < 200) @@ -1762,7 +1762,7 @@ static void process_dev(char *devname) #ifndef WIN_STANDBYNOW2 #define WIN_STANDBYNOW2 0x94 #endif - printf(" issuing standby command\n"); + puts(" issuing standby command"); args[0] = WIN_STANDBYNOW1; ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); } @@ -1773,13 +1773,13 @@ static void process_dev(char *devname) #ifndef WIN_SLEEPNOW2 #define WIN_SLEEPNOW2 0x99 #endif - printf(" issuing sleep command\n"); + puts(" issuing sleep command"); args[0] = WIN_SLEEPNOW1; ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); } if (set_seagate) { args[0] = 0xfb; - printf(" disabling Seagate auto powersaving mode\n"); + puts(" disabling Seagate auto powersaving mode"); ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); } if (getset_standby == IS_SET) { @@ -1815,17 +1815,17 @@ static void process_dev(char *devname) if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) { printf(" IO_support\t=%3ld (", parm); if (parm == 0) - printf("default 16-bit)\n"); + puts("default 16-bit)"); else if (parm == 2) - printf("16-bit)\n"); + puts("16-bit)"); else if (parm == 1) - printf("32-bit)\n"); + puts("32-bit)"); else if (parm == 3) - printf("32-bit w/sync)\n"); + puts("32-bit w/sync)"); else if (parm == 8) - printf("Request-Queue-Bypass)\n"); + puts("Request-Queue-Bypass)"); else - printf("\?\?\?)\n"); + puts("\?\?\?)"); } } if (getset_unmask) { @@ -1837,7 +1837,7 @@ static void process_dev(char *devname) if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) { printf(fmt, "using_dma", parm); if (parm == 8) - printf(" (DMA-Assisted-PIO)\n"); + puts(" (DMA-Assisted-PIO)"); else on_off(parm != 0); } @@ -1921,7 +1921,7 @@ static void process_dev(char *devname) id.multsect_valid &= ~1; dump_identity(&id); } else if (errno == -ENOMSG) - printf(" no identification info available\n"); + puts(" no identification info available"); else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ bb_perror_msg("HDIO_GET_IDENTITY"); else diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 4b26b7bdc..292ff88dd 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -701,7 +701,7 @@ int i2cset_main(int argc, char **argv) } if (status < 0) { - printf("Warning - readback failed\n"); + puts("Warning - readback failed"); } else if (status != val) { printf("Warning - data mismatch - wrote " @@ -756,8 +756,8 @@ static void dump_data(int bus_fd, int mode, unsigned first, { int i, j, res; - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" - " 0123456789abcdef\n"); + puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" + " 0123456789abcdef"); for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) { if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) @@ -826,22 +826,22 @@ static void dump_data(int bus_fd, int mode, unsigned first, break; /* Skip unwanted registers */ if (i+j < first || i+j > last) { - printf(" "); + bb_putchar(' '); continue; } res = block[i+j]; if (res < 0) { - printf("X"); + bb_putchar('X'); } else if (res == 0x00 || res == 0xff) { - printf("."); + bb_putchar('.'); } else if (res < 32 || res >= 127) { - printf("?"); + bb_putchar('?'); } else { - printf("%c", res); + bb_putchar(res); } } - printf("\n"); + bb_putchar('\n'); } } @@ -850,7 +850,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) int i, j, rv; /* Word data. */ - printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); + puts(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f"); for (i = 0; i < 256; i += 8) { if (i/8 < first/8) continue; @@ -871,7 +871,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) else printf("%04x ", rv & 0xffff); } - printf("\n"); + bb_putchar('\n'); } } @@ -1267,7 +1267,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) if (!(opts & opt_y)) confirm_action(-1, -1, -1, 0); - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"); for (i = 0; i < 128; i += 16) { printf("%02x: ", i); for(j = 0; j < 16; j++) { @@ -1325,7 +1325,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) else printf("%02x ", i+j); } - printf("\n"); + bb_putchar('\n'); } return 0; diff --git a/networking/arping.c b/networking/arping.c index ce7fa299c..ef205e5e6 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -249,7 +249,7 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) unsigned diff = MONOTONIC_US() - last; printf(" %u.%03ums\n", diff / 1000, diff % 1000); } else { - printf(" UNSOLICITED?\n"); + puts(" UNSOLICITED?"); } fflush_all(); } diff --git a/networking/brctl.c b/networking/brctl.c index 8043d600b..c01a86998 100644 --- a/networking/brctl.c +++ b/networking/brctl.c @@ -217,7 +217,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) arm_ioctl(args, BRCTL_GET_BRIDGES, (unsigned long) bridx, MAX_PORTS); num = xioctl(fd, SIOCGIFBR, args); - printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n"); + puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); for (i = 0; i < num; i++) { char ifname[IFNAMSIZ]; int j, tabs; @@ -236,7 +236,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) /* print bridge id */ x = (unsigned char *) &bi.bridge_id; for (j = 0; j < 8; j++) { - printf("%.2x", x[j]); + printf("%02x", x[j]); if (j == 1) bb_putchar('.'); } diff --git a/printutils/lpd.c b/printutils/lpd.c index eaf42c08b..c98bbb347 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c @@ -200,7 +200,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) if (2 != s[0] && 3 != s[0]) goto unsupported_cmd; if (spooling & (1 << (s[0]-1))) { - printf("Duplicated subcommand\n"); + puts("Duplicated subcommand"); goto err_exit; } // get filename @@ -208,7 +208,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) fname = strchr(s, ' '); if (!fname) { // bad_fname: - printf("No or bad filename\n"); + puts("No or bad filename"); goto err_exit; } *fname++ = '\0'; @@ -219,13 +219,13 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) // get length expected_len = bb_strtou(s + 1, NULL, 10); if (errno || expected_len < 0) { - printf("Bad length\n"); + puts("Bad length"); goto err_exit; } if (2 == s[0] && expected_len > 16 * 1024) { // SECURITY: // ctrlfile can't be big (we want to read it back later!) - printf("File is too big\n"); + puts("File is too big"); goto err_exit; } diff --git a/procps/iostat.c b/procps/iostat.c index 8d272c87c..c290c594b 100644 --- a/procps/iostat.c +++ b/procps/iostat.c @@ -142,7 +142,7 @@ static void print_timestamp(void) /* %x: date representation for the current locale */ /* %X: time representation for the current locale */ strftime(buf, sizeof(buf), "%x %X", &G.tmtime); - printf("%s\n", buf); + puts(buf); } static cputime_t get_smp_uptime(void) diff --git a/procps/powertop.c b/procps/powertop.c index 1de5d329e..18418100f 100644 --- a/procps/powertop.c +++ b/procps/powertop.c @@ -704,7 +704,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) /* Get number of CPUs */ G.total_cpus = get_cpu_count(); - printf("Collecting data for "DEFAULT_SLEEP_STR" seconds\n"); + puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); #if ENABLE_FEATURE_USE_TERMIOS tcgetattr(0, (void *)&G.init_settings); diff --git a/shell/ash.c b/shell/ash.c index b835415b5..7d20b8860 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9681,7 +9681,7 @@ preadfd(void) } # if ENABLE_ASH_IDLE_TIMEOUT else if (errno == EAGAIN && timeout > 0) { - printf("\007timed out waiting for input: auto-logout\n"); + puts("\007timed out waiting for input: auto-logout"); exitshell(); } # endif diff --git a/shell/hush.c b/shell/hush.c index bccd9c1e9..f085ed3eb 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6794,7 +6794,7 @@ static int checkjobs(struct pipe *fg_pipe) int sig = WTERMSIG(status); if (i == fg_pipe->num_cmds-1) /* TODO: use strsignal() instead for bash compat? but that's bloat... */ - printf("%s\n", sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); + puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? * Maybe we need to use sig | 128? */ diff --git a/shell/shell_common.c b/shell/shell_common.c index 2b6f7dc92..8c9607c8c 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -380,7 +380,7 @@ static void printlim(unsigned opts, const struct rlimit *limit, val = limit->rlim_cur; if (val == RLIM_INFINITY) - printf("unlimited\n"); + puts("unlimited"); else { val >>= l->factor_shift; printf("%llu\n", (long long) val); diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c index 6f49cec8f..6ef6445e6 100644 --- a/util-linux/fdformat.c +++ b/util-linux/fdformat.c @@ -93,7 +93,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) } xioctl(fd, FDFMTEND, NULL); - printf("done\n"); + puts("Done"); /* VERIFY */ if (verify) { @@ -126,7 +126,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) if (ENABLE_FEATURE_CLEAN_UP) free(data); - printf("done\n"); + puts("Done"); } if (ENABLE_FEATURE_CLEAN_UP) close(fd); diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 7fe70fb72..f49ce95a4 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -1102,11 +1102,11 @@ warn_geometry(void) printf(" sectors"); if (!g_cylinders) printf(" cylinders"); - printf( #if ENABLE_FEATURE_FDISK_WRITABLE - " (settable in the extra functions menu)" + puts(" (settable in the extra functions menu)"); +#else + bb_putchar('\n'); #endif - "\n"); return 1; } @@ -1150,7 +1150,7 @@ read_extended(int ext) p = pex->part_table; if (!get_start_sect(p)) { - printf("Bad offset in primary extended partition\n"); + puts("Bad offset in primary extended partition"); return; } @@ -1450,8 +1450,8 @@ static int get_boot(void) current_label_type = LABEL_OSF; return 0; } - printf("This disk has both DOS and BSD magic.\n" - "Give the 'b' command to go to BSD mode.\n"); + puts("This disk has both DOS and BSD magic.\n" + "Give the 'b' command to go to BSD mode."); } #endif @@ -1461,9 +1461,9 @@ static int get_boot(void) #else if (!valid_part_table_flag(MBRbuffer)) { if (what == OPEN_MAIN) { - printf("Device contains neither a valid DOS " - "partition table, nor Sun, SGI, OSF or GPT " - "disklabel\n"); + puts("Device contains neither a valid DOS " + "partition table, nor Sun, SGI, OSF or GPT " + "disklabel"); #ifdef __sparc__ IF_FEATURE_SUN_LABEL(create_sunlabel();) #else @@ -1596,7 +1596,7 @@ read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char * } if (value >= low && value <= high) break; - printf("Value is out of range\n"); + puts("Value is out of range"); } return value; } @@ -1641,7 +1641,7 @@ get_existing_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("No partition is defined yet!\n"); + puts("No partition is defined yet!"); return -1; not_unique: @@ -1668,7 +1668,7 @@ get_nonexisting_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("All primary partitions have been defined already!\n"); + puts("All primary partitions have been defined already!"); return -1; not_unique: @@ -1703,10 +1703,10 @@ toggle_dos_compatibility_flag(void) dos_compatible_flag = 1 - dos_compatible_flag; if (dos_compatible_flag) { sector_offset = g_sectors; - printf("DOS Compatibility flag is set\n"); + printf("DOS Compatibility flag is %sset\n", ""); } else { sector_offset = 1; - printf("DOS Compatibility flag is not set\n"); + printf("DOS Compatibility flag is %sset\n", "not "); } } @@ -1813,16 +1813,16 @@ change_sysid(void) sys = read_hex(get_sys_types()); if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { - printf("Type 0 means free space to many systems\n" - "(but not to Linux). Having partitions of\n" - "type 0 is probably unwise.\n"); + puts("Type 0 means free space to many systems\n" + "(but not to Linux). Having partitions of\n" + "type 0 is probably unwise."); /* break; */ } if (!LABEL_IS_SUN && !LABEL_IS_SGI) { if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { - printf("You cannot change a partition into" - " an extended one or vice versa\n"); + puts("You cannot change a partition into" + " an extended one or vice versa"); break; } } @@ -1830,10 +1830,10 @@ change_sysid(void) if (sys < 256) { #if ENABLE_FEATURE_SUN_LABEL if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) - printf("Consider leaving partition 3 " - "as Whole disk (5),\n" - "as SunOS/Solaris expects it and " - "even Linux likes it\n\n"); + puts("Consider leaving partition 3 " + "as Whole disk (5),\n" + "as SunOS/Solaris expects it and " + "even Linux likes it\n"); #endif #if ENABLE_FEATURE_SGI_LABEL if (LABEL_IS_SGI && @@ -1842,10 +1842,10 @@ change_sysid(void) (i == 8 && sys != 0) ) ) { - printf("Consider leaving partition 9 " - "as volume header (0),\nand " - "partition 11 as entire volume (6)" - "as IRIX expects it\n\n"); + puts("Consider leaving partition 9 " + "as volume header (0),\nand " + "partition 11 as entire volume (6)" + "as IRIX expects it\n"); } #endif if (sys == origsys) @@ -2067,7 +2067,7 @@ fix_partition_table_order(void) int i,k; if (!wrong_p_order(NULL)) { - printf("Ordering is already correct\n\n"); + puts("Ordering is already correct\n"); return; } @@ -2095,7 +2095,7 @@ fix_partition_table_order(void) if (i) fix_chain_of_logicals(); - printf("Done.\n"); + puts("Done"); } #endif @@ -2178,7 +2178,7 @@ list_table(int xtra) * if this is a sgi, sun or aix labeled disk... */ if (LABEL_IS_DOS && wrong_p_order(NULL)) { /* FIXME */ - printf("\nPartition table entries are not in disk order\n"); + puts("\nPartition table entries are not in disk order"); } } @@ -2192,7 +2192,7 @@ x_list_table(int extend) printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", disk_device, g_heads, g_sectors, g_cylinders); - printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); + puts("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID"); for (i = 0; i < g_partitions; i++) { pe = &ptes[i]; p = (extend ? pe->ext_pointer : pe->part_table); @@ -2419,7 +2419,7 @@ add_partition(int n, int sys) limit = first[i] - 1; } if (start > limit) { - printf("No free sectors available\n"); + puts("No free sectors available"); if (n > 4) g_partitions--; return; @@ -2490,9 +2490,9 @@ new_partition(void) return; } if (LABEL_IS_AIX) { - printf("Sorry - this fdisk cannot handle AIX disk labels.\n" + puts("Sorry - this fdisk cannot handle AIX disk labels.\n" "If you want to add DOS-type partitions, create a new empty DOS partition\n" -"table first (use 'o'). This will destroy the present disk contents.\n"); +"table first (use 'o'). This will destroy the present disk contents."); return; } @@ -2500,7 +2500,7 @@ new_partition(void) free_primary += !ptes[i].part_table->sys_ind; if (!free_primary && g_partitions >= MAXIMUM_PARTS) { - printf("The maximum number of partitions has been created\n"); + puts("The maximum number of partitions has been created"); return; } @@ -2508,8 +2508,8 @@ new_partition(void) if (extended_offset) add_logical(); else - printf("You must delete some partition and add " - "an extended partition first\n"); + puts("You must delete some partition and add " + "an extended partition first"); } else { char c, line[80]; snprintf(line, sizeof(line), @@ -2547,7 +2547,7 @@ reread_partition_table(int leave) { int i; - printf("Calling ioctl() to re-read partition table\n"); + puts("Calling ioctl() to re-read partition table"); sync(); /* Users with slow external USB disks on a 320MHz ARM system (year 2011) * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: @@ -2558,10 +2558,10 @@ reread_partition_table(int leave) "failed, kernel still uses old table"); #if 0 if (dos_changed) - printf( + puts( "\nWARNING: If you have created or modified any DOS 6.x\n" "partitions, please see the fdisk manual page for additional\n" - "information\n"); + "information"); #endif if (leave) { @@ -2589,7 +2589,7 @@ write_table(void) } } else if (LABEL_IS_SGI) { - /* no test on change? the printf below might be mistaken */ + /* no test on change? the "altered" msg below might be mistaken */ sgi_write_table(); } else if (LABEL_IS_SUN) { @@ -2601,7 +2601,7 @@ write_table(void) } } - printf("The partition table has been altered.\n"); + puts("The partition table has been altered."); reread_partition_table(1); } #endif /* FEATURE_FDISK_WRITABLE */ @@ -2744,8 +2744,8 @@ xselect(void) user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); if (dos_compatible_flag) { sector_offset = g_sectors; - printf("Warning: setting sector offset for DOS " - "compatiblity\n"); + puts("Warning: setting sector offset for DOS " + "compatiblity"); } update_units(); break; @@ -3024,7 +3024,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) sgi_get_bootfile()); if (read_maybe_empty("Please enter the name of the " "new boot file: ") == '\n') - printf("Boot file unchanged\n"); + puts("Boot file unchanged"); else sgi_set_bootfile(line_ptr); } @@ -3106,8 +3106,8 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_FDISK_ADVANCED case 'x': if (LABEL_IS_SGI) { - printf("\n\tSorry, no experts menu for SGI " - "partition tables available\n\n"); + puts("\n\tSorry, no experts menu for SGI " + "partition tables available\n"); } else xselect(); break; diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 5786d5f7d..715e227ca 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c @@ -106,7 +106,7 @@ gpt_list_table(int xtra UNUSED_PARAM) (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba), (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba)); - printf("Number Start (sector) End (sector) Size Code Name\n"); + puts("Number Start (sector) End (sector) Size Code Name"); for (i = 0; i < n_parts; i++) { gpt_partition *p = gpt_part(i); if (p->lba_start) { @@ -119,7 +119,7 @@ gpt_list_table(int xtra UNUSED_PARAM) numstr6, 0x0700 /* FIXME */); gpt_print_wide(p->name, 18); - printf("\n"); + bb_putchar('\n'); } } } diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index 33767a1af..d2f3524b4 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c @@ -371,9 +371,9 @@ static int ask(const char *string, int def) } } if (def) - printf("y\n"); + puts("y"); else { - printf("n\n"); + puts("n"); errors_uncorrected = 1; } return def; @@ -405,7 +405,7 @@ static void check_mount(void) if (isatty(0) && isatty(1)) cont = ask("Do you really want to continue", 0); if (!cont) { - printf("Check aborted\n"); + puts("Check aborted"); exit(EXIT_SUCCESS); } } @@ -470,8 +470,8 @@ static void write_block(unsigned nr, void *addr) if (!nr) return; if (nr < FIRSTZONE || nr >= ZONES) { - printf("Internal error: trying to write bad block\n" - "Write request ignored\n"); + puts("Internal error: trying to write bad block\n" + "Write request ignored"); errors_uncorrected = 1; return; } @@ -659,7 +659,7 @@ static void read_tables(void) if (INODE_BUFFER_SIZE != read(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) die("can't read inodes"); if (NORM_FIRSTZONE != FIRSTZONE) { - printf("warning: firstzone!=norm_firstzone\n"); + puts("warning: firstzone!=norm_firstzone"); errors_uncorrected = 1; } get_dirsize(); @@ -713,7 +713,7 @@ static void get_inode_common(unsigned nr, uint16_t i_mode) } else links++; if (!++inode_count[nr]) { - printf("Warning: inode count too big\n"); + puts("Warning: inode count too big"); inode_count[nr]--; errors_uncorrected = 1; } @@ -1299,7 +1299,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) } if (changed) { write_tables(); - printf("FILE SYSTEM HAS BEEN CHANGED\n"); + puts("FILE SYSTEM HAS BEEN CHANGED"); sync(); } else if (OPT_repair) write_superblock(); diff --git a/util-linux/getopt.c b/util-linux/getopt.c index 58df1c823..b9dadf13c 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c @@ -378,7 +378,7 @@ int getopt_main(int argc, char **argv) if (compatible) { /* For some reason, the original getopt gave no error * when there were no arguments. */ - printf(" --\n"); + puts(" --"); return 0; } bb_error_msg_and_die("missing optstring argument"); diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 888f70ef8..38d81af50 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c @@ -119,7 +119,7 @@ int ipcrm_main(int argc, char **argv) if (remove_ids(what, &argv[2])) fflush_stdout_and_exit(EXIT_FAILURE); - printf("resource(s) deleted\n"); + puts("resource(s) deleted"); return 0; } } -- cgit v1.2.3-55-g6feb From 4700fb5bead95d6457b943351b7dc6f49a09683e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Oct 2015 15:40:13 +0200 Subject: ash: make dowait() a bit more readable. Logic is unchanged Signed-off-by: Denys Vlasenko --- shell/ash.c | 58 +++++++++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 7d20b8860..38ff4b62e 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -3919,19 +3919,15 @@ sprint_status48(char *s, int status, int sigonly) col = 0; if (!WIFEXITED(status)) { -#if JOBS - if (WIFSTOPPED(status)) + if (JOBS && WIFSTOPPED(status)) st = WSTOPSIG(status); else -#endif st = WTERMSIG(status); if (sigonly) { if (st == SIGINT || st == SIGPIPE) goto out; -#if JOBS - if (WIFSTOPPED(status)) + if (JOBS && WIFSTOPPED(status)) goto out; -#endif } st &= 0x7f; //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata @@ -3955,7 +3951,6 @@ dowait(int wait_flags, struct job *job) int status; struct job *jp; struct job *thisjob; - int state; TRACE(("dowait(0x%x) called\n", wait_flags)); @@ -3973,11 +3968,12 @@ dowait(int wait_flags, struct job *job) INT_OFF; thisjob = NULL; for (jp = curjob; jp; jp = jp->prev_job) { + int jobstate; struct procstat *ps; struct procstat *psend; if (jp->state == JOBDONE) continue; - state = JOBDONE; + jobstate = JOBDONE; ps = jp->ps; psend = ps + jp->nprocs; do { @@ -3989,41 +3985,41 @@ dowait(int wait_flags, struct job *job) thisjob = jp; } if (ps->ps_status == -1) - state = JOBRUNNING; + jobstate = JOBRUNNING; #if JOBS - if (state == JOBRUNNING) + if (jobstate == JOBRUNNING) continue; if (WIFSTOPPED(ps->ps_status)) { jp->stopstatus = ps->ps_status; - state = JOBSTOPPED; + jobstate = JOBSTOPPED; } #endif } while (++ps < psend); - if (thisjob) - goto gotjob; - } -#if JOBS - if (!WIFSTOPPED(status)) -#endif - jobless--; - goto out; - - gotjob: - if (state != JOBRUNNING) { - thisjob->changed = 1; + if (!thisjob) + continue; - if (thisjob->state != state) { - TRACE(("Job %d: changing state from %d to %d\n", - jobno(thisjob), thisjob->state, state)); - thisjob->state = state; + /* Found the job where one of its processes changed its state. + * Is there at least one live and running process in this job? */ + if (jobstate != JOBRUNNING) { + /* No. All live processes in the job are stopped + * (JOBSTOPPED) or there are no live processes (JOBDONE) + */ + thisjob->changed = 1; + if (thisjob->state != jobstate) { + TRACE(("Job %d: changing state from %d to %d\n", + jobno(thisjob), thisjob->state, jobstate)); + thisjob->state = jobstate; #if JOBS - if (state == JOBSTOPPED) { - set_curjob(thisjob, CUR_STOPPED); - } + if (jobstate == JOBSTOPPED) + set_curjob(thisjob, CUR_STOPPED); #endif + } } + goto out; } - + /* The process wasn't found in job list */ + if (JOBS && !WIFSTOPPED(status)) + jobless--; out: INT_ON; -- cgit v1.2.3-55-g6feb From 2384162f6462f232a0d709e64f7d20bb3dbca503 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Oct 2015 15:52:03 +0200 Subject: ash: simplify "you have mail" code function old new delta mailtime_hash - 4 +4 redirect 1282 1280 -2 mailtime 40 - -40 cmdloop 429 378 -51 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 0/2 up/down: 4/-93) Total: -89 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 38ff4b62e..07e7f621a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10029,10 +10029,8 @@ setinputstring(char *string) #if ENABLE_ASH_MAIL -#define MAXMBOXES 10 - -/* times of mailboxes */ -static time_t mailtime[MAXMBOXES]; +/* Hash of mtimes of mailboxes */ +static unsigned mailtime_hash; /* Set if MAIL or MAILPATH is changed. */ static smallint mail_var_path_changed; @@ -10048,13 +10046,14 @@ chkmail(void) const char *mpath; char *p; char *q; - time_t *mtp; + unsigned new_hash; struct stackmark smark; struct stat statb; setstackmark(&smark); mpath = mpathset() ? mpathval() : mailval(); - for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) { + new_hash = 0; + for (;;) { p = path_advance(&mpath, nullstr); if (p == NULL) break; @@ -10068,16 +10067,14 @@ chkmail(void) #endif q[-1] = '\0'; /* delete trailing '/' */ if (stat(p, &statb) < 0) { - *mtp = 0; continue; } - if (!mail_var_path_changed && statb.st_mtime != *mtp) { - fprintf( - stderr, "%s\n", - pathopt ? pathopt : "you have mail" - ); - } - *mtp = statb.st_mtime; + /* Very simplistic "hash": just a sum of all mtimes */ + new_hash += (unsigned)statb.st_mtime; + } + if (!mail_var_path_changed && mailtime_hash != new_hash) { + mailtime_hash = new_hash; + out2str("you have mail\n"); } mail_var_path_changed = 0; popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 4cd99e7c6c1af77721b890ed5ae26d747796c4bd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Oct 2015 16:02:53 +0200 Subject: ash: "you have mail" should ignore first change in mtime Signed-off-by: Denys Vlasenko --- shell/ash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 07e7f621a..b09681296 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10073,8 +10073,9 @@ chkmail(void) new_hash += (unsigned)statb.st_mtime; } if (!mail_var_path_changed && mailtime_hash != new_hash) { + if (mailtime_hash != 0) + out2str("you have mail\n"); mailtime_hash = new_hash; - out2str("you have mail\n"); } mail_var_path_changed = 0; popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 550bf5b4a418378cd8f9fbbf5252fe57acdacb5a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Oct 2015 16:42:57 +0200 Subject: remove global "jmp_buf die_jmp" from !FEATURE_PREFER_APPLETS builds function old new delta xfunc_has_died - 21 +21 sleep_much - 12 +12 sleep10 - 9 +9 die_func - 4 +4 fflush_stdout_and_exit 35 36 +1 builtin_type 121 119 -2 die_sleep 4 - -4 xfunc_die 60 24 -36 hush_main 1128 1011 -117 die_jmp 156 - -156 ------------------------------------------------------------------------------ (add/remove: 4/2 grow/shrink: 1/3 up/down: 47/-315) Total: -268 bytes text data bss dec hex filename 939992 992 17652 958636 ea0ac busybox_old 939880 992 17496 958368 e9fa0 busybox_unstripped Signed-off-by: Denys Vlasenko --- include/libbb.h | 3 +-- init/init.c | 9 +++++++-- libbb/fflush_stdout_and_exit.c | 13 ++++--------- libbb/vfork_daemon_rexec.c | 39 +++++++++++++++++++++++++-------------- libbb/xfunc_die.c | 26 ++++---------------------- loginutils/getty.c | 7 ++++++- shell/hush.c | 25 ++++++++++++++----------- 7 files changed, 61 insertions(+), 61 deletions(-) (limited to 'shell') diff --git a/include/libbb.h b/include/libbb.h index d79843a2d..2f24ecbc3 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1127,9 +1127,8 @@ enum { extern const char *msg_eol; extern smallint syslog_level; extern smallint logmode; -extern int die_sleep; extern uint8_t xfunc_error_retval; -extern jmp_buf die_jmp; +extern void (*die_func)(void); extern void xfunc_die(void) NORETURN FAST_FUNC; extern void bb_show_usage(void) NORETURN FAST_FUNC; extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; diff --git a/init/init.c b/init/init.c index b2fe85635..80c5d0f74 100644 --- a/init/init.c +++ b/init/init.c @@ -1015,6 +1015,11 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) } #endif +static void sleep_much(void) +{ + sleep(30 * 24*60*60); +} + int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int init_main(int argc UNUSED_PARAM, char **argv) { @@ -1051,12 +1056,12 @@ int init_main(int argc UNUSED_PARAM, char **argv) /* If, say, xmalloc would ever die, we don't want to oops kernel * by exiting. - * NB: we set die_sleep *after* PID 1 check and bb_show_usage. + * NB: we set die_func *after* PID 1 check and bb_show_usage. * Otherwise, for example, "init u" ("please rexec yourself" * command for sysvinit) will show help text (which isn't too bad), * *and sleep forever* (which is bad!) */ - die_sleep = 30 * 24*60*60; + die_func = sleep_much; /* Figure out where the default console should be */ console_init(); diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index 9ad5dbf96..b4bed865f 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c @@ -15,15 +15,10 @@ void FAST_FUNC fflush_stdout_and_exit(int retval) { + xfunc_error_retval = retval; if (fflush(stdout)) bb_perror_msg_and_die(bb_msg_standard_output); - - if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { - /* We are in NOFORK applet. Do not exit() directly, - * but use xfunc_die() */ - xfunc_error_retval = retval; - xfunc_die(); - } - - exit(retval); + /* In case we are in NOFORK applet. Do not exit() directly, + * but use xfunc_die() */ + xfunc_die(); } diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index ed1f86f0c..d6ca7b263 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -69,28 +69,44 @@ pid_t FAST_FUNC xspawn(char **argv) } #if ENABLE_FEATURE_PREFER_APPLETS +static jmp_buf die_jmp; +static void jump(void) +{ + /* Special case. We arrive here if NOFORK applet + * calls xfunc, which then decides to die. + * We don't die, but jump instead back to caller. + * NOFORK applets still cannot carelessly call xfuncs: + * p = xmalloc(10); + * q = xmalloc(10); // BUG! if this dies, we leak p! + */ + /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). + * This works because exitcodes are bytes, + * run_nofork_applet() ensures that by "& 0xff" */ + longjmp(die_jmp, xfunc_error_retval | 0x100); +} + struct nofork_save_area { jmp_buf die_jmp; + void (*die_func)(void); const char *applet_name; uint32_t option_mask32; - int die_sleep; uint8_t xfunc_error_retval; }; static void save_nofork_data(struct nofork_save_area *save) { memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); + save->die_func = die_func; save->applet_name = applet_name; - save->xfunc_error_retval = xfunc_error_retval; save->option_mask32 = option_mask32; - save->die_sleep = die_sleep; + save->xfunc_error_retval = xfunc_error_retval; } static void restore_nofork_data(struct nofork_save_area *save) { memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); + die_func = save->die_func; applet_name = save->applet_name; - xfunc_error_retval = save->xfunc_error_retval; option_mask32 = save->option_mask32; - die_sleep = save->die_sleep; + xfunc_error_retval = save->xfunc_error_retval; } int FAST_FUNC run_nofork_applet(int applet_no, char **argv) @@ -133,11 +149,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) while (argv[argc]) argc++; - /* Special flag for xfunc_die(). If xfunc will "die" - * in NOFORK applet, xfunc_die() sees negative - * die_sleep and longjmp here instead. */ - die_sleep = -1; - + /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ + die_func = jump; rc = setjmp(die_jmp); if (!rc) { /* Some callers (xargs) @@ -146,10 +159,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); /* Finally we can call NOFORK applet's main() */ rc = applet_main[applet_no](argc, tmp_argv); - } else { /* xfunc died in NOFORK applet */ - /* in case they meant to return 0... */ - if (rc == -2222) - rc = 0; + } else { + /* xfunc died in NOFORK applet */ } /* Restoring some globals */ diff --git a/libbb/xfunc_die.c b/libbb/xfunc_die.c index 204e5e49d..73f7998e5 100644 --- a/libbb/xfunc_die.c +++ b/libbb/xfunc_die.c @@ -7,34 +7,16 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ -/* Keeping it separate allows to NOT suck in stdio for VERY small applets. +/* Keeping it separate allows to NOT pull in stdio for VERY small applets. * Try building busybox with only "true" enabled... */ #include "libbb.h" -int die_sleep; -#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH -jmp_buf die_jmp; -#endif +void (*die_func)(void); void FAST_FUNC xfunc_die(void) { - if (die_sleep) { - if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) - && die_sleep < 0 - ) { - /* Special case. We arrive here if NOFORK applet - * calls xfunc, which then decides to die. - * We don't die, but jump instead back to caller. - * NOFORK applets still cannot carelessly call xfuncs: - * p = xmalloc(10); - * q = xmalloc(10); // BUG! if this dies, we leak p! - */ - /* -2222 means "zero" (longjmp can't pass 0) - * run_nofork_applet() catches -2222. */ - longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); - } - sleep(die_sleep); - } + if (die_func) + die_func(); exit(xfunc_error_retval); } diff --git a/loginutils/getty.c b/loginutils/getty.c index 174542841..762d5c773 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -520,6 +520,11 @@ static void alarm_handler(int sig UNUSED_PARAM) _exit(EXIT_SUCCESS); } +static void sleep10(void) +{ + sleep(10); +} + int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int getty_main(int argc UNUSED_PARAM, char **argv) { @@ -599,7 +604,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) close(n--); /* Logging. We want special flavor of error_msg_and_die */ - die_sleep = 10; + die_func = sleep10; msg_eol = "\r\n"; /* most likely will internally use fd #3 in CLOEXEC mode: */ openlog(applet_name, LOG_PID, LOG_AUTH); diff --git a/shell/hush.c b/shell/hush.c index f085ed3eb..0d107715f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1479,10 +1479,11 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler) #if ENABLE_HUSH_JOB +static void xfunc_has_died(void); /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ -# define disable_restore_tty_pgrp_on_exit() (die_sleep = 0) +# define disable_restore_tty_pgrp_on_exit() (die_func = NULL) /* After [v]fork, in parent: restore tty pgrp on xfunc death */ -# define enable_restore_tty_pgrp_on_exit() (die_sleep = -1) +# define enable_restore_tty_pgrp_on_exit() (die_func = xfunc_has_died) /* Restores tty foreground process group, and exits. * May be called as signal handler for fatal signal @@ -1587,6 +1588,15 @@ static void hush_exit(int exitcode) #endif } +static void xfunc_has_died(void) NORETURN; +static void xfunc_has_died(void) +{ + /* xfunc has failed! die die die */ + /* no EXIT traps, this is an escape hatch! */ + G.exiting = 1; + hush_exit(xfunc_error_retval); +} + //TODO: return a mask of ALL handled sigs? static int check_and_run_traps(void) @@ -7866,12 +7876,7 @@ int hush_main(int argc, char **argv) /* Initialize some more globals to non-zero values */ cmdedit_update_prompt(); - if (setjmp(die_jmp)) { - /* xfunc has failed! die die die */ - /* no EXIT traps, this is an escape hatch! */ - G.exiting = 1; - hush_exit(xfunc_error_retval); - } + die_func = xfunc_has_died; /* Shell is non-interactive at first. We need to call * install_special_sighandlers() if we are going to execute "sh