From 19358cc31317dca4642417066c1445ce00438e18 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 5 Aug 2018 15:42:29 +0200 Subject: ash,hush: fold shell_builtin_read() way-too-many params into a struct param function old new delta getoptscmd 587 584 -3 readcmd 240 224 -16 shell_builtin_read 1426 1399 -27 builtin_read 210 182 -28 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-74) Total: -74 bytes Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 55 +++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) (limited to 'shell/shell_common.c') diff --git a/shell/shell_common.c b/shell/shell_common.c index 0a07296..f2bf5ab 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -46,16 +46,7 @@ int FAST_FUNC is_well_formed_var_name(const char *s, char terminator) //Here we can simply store "VAR=" at buffer start and store read data directly //after "=", then pass buffer to setvar() to consume. const char* FAST_FUNC -shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), - char **argv, - const char *ifs, - int read_flags, - const char *opt_n, - const char *opt_p, - const char *opt_t, - const char *opt_u, - const char *opt_d -) +shell_builtin_read(struct builtin_read_params *params) { struct pollfd pfd[1]; #define fd (pfd[0].fd) /* -u FD */ @@ -70,9 +61,13 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), int bufpos; /* need to be able to hold -1 */ int startword; smallint backslash; + char **argv; + const char *ifs; + int read_flags; errno = err = 0; + argv = params->argv; pp = argv; while (*pp) { if (!is_well_formed_var_name(*pp, '\0')) { @@ -84,29 +79,29 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), } nchars = 0; /* if != 0, -n is in effect */ - if (opt_n) { - nchars = bb_strtou(opt_n, NULL, 10); + if (params->opt_n) { + nchars = bb_strtou(params->opt_n, NULL, 10); if (nchars < 0 || errno) return "invalid count"; /* note: "-n 0": off (bash 3.2 does this too) */ } end_ms = 0; - if (opt_t && !ENABLE_FEATURE_SH_READ_FRAC) { - end_ms = bb_strtou(opt_t, NULL, 10); + if (params->opt_t && !ENABLE_FEATURE_SH_READ_FRAC) { + end_ms = bb_strtou(params->opt_t, NULL, 10); if (errno) return "invalid timeout"; if (end_ms > UINT_MAX / 2048) /* be safely away from overflow */ end_ms = UINT_MAX / 2048; end_ms *= 1000; } - if (opt_t && ENABLE_FEATURE_SH_READ_FRAC) { + if (params->opt_t && ENABLE_FEATURE_SH_READ_FRAC) { /* bash 4.3 (maybe earlier) supports -t N.NNNNNN */ char *p; /* Eat up to three fractional digits */ int frac_digits = 3 + 1; - end_ms = bb_strtou(opt_t, &p, 10); + end_ms = bb_strtou(params->opt_t, &p, 10); if (end_ms > UINT_MAX / 2048) /* be safely away from overflow */ end_ms = UINT_MAX / 2048; @@ -128,13 +123,13 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), } fd = STDIN_FILENO; - if (opt_u) { - fd = bb_strtou(opt_u, NULL, 10); + if (params->opt_u) { + fd = bb_strtou(params->opt_u, NULL, 10); if (fd < 0 || errno) return "invalid file descriptor"; } - if (opt_t && end_ms == 0) { + if (params->opt_t && end_ms == 0) { /* "If timeout is 0, read returns immediately, without trying * to read any data. The exit status is 0 if input is available * on the specified file descriptor, non-zero otherwise." @@ -147,14 +142,16 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), return (const char *)(uintptr_t)(r <= 0); } - if (opt_p && isatty(fd)) { - fputs(opt_p, stderr); + if (params->opt_p && isatty(fd)) { + fputs(params->opt_p, stderr); fflush_all(); } + ifs = params->ifs; if (ifs == NULL) ifs = defifs; + read_flags = params->read_flags; if (nchars || (read_flags & BUILTIN_READ_SILENT)) { tcgetattr(fd, &tty); old_tty = tty; @@ -181,11 +178,11 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), retval = (const char *)(uintptr_t)0; startword = 1; backslash = 0; - if (opt_t) + if (params->opt_t) end_ms += (unsigned)monotonic_ms(); buffer = NULL; bufpos = 0; - delim = opt_d ? *opt_d : '\n'; + delim = params->opt_d ? params->opt_d[0] : '\n'; do { char c; int timeout; @@ -194,7 +191,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), buffer = xrealloc(buffer, bufpos + 0x101); timeout = -1; - if (opt_t) { + if (params->opt_t) { timeout = end_ms - (unsigned)monotonic_ms(); /* ^^^^^^^^^^^^^ all values are unsigned, * wrapping math is used here, good even if @@ -246,7 +243,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), * without variable names (bash compat). * Thus, "read" and "read REPLY" are not the same. */ - if (!opt_d && argv[0]) { + if (!params->opt_d && argv[0]) { /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */ const char *is_ifs = strchr(ifs, c); if (startword && is_ifs) { @@ -261,7 +258,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), if (argv[1] != NULL && is_ifs) { buffer[bufpos] = '\0'; bufpos = 0; - setvar(*argv, buffer); + params->setvar(*argv, buffer); argv++; /* can we skip one non-space ifs char? (2: yes) */ startword = isspace(c) ? 2 : 1; @@ -313,14 +310,14 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), } /* Use the remainder as a value for the next variable */ - setvar(*argv, buffer); + params->setvar(*argv, buffer); /* Set the rest to "" */ while (*++argv) - setvar(*argv, ""); + params->setvar(*argv, ""); } else { /* Note: no $IFS removal */ buffer[bufpos] = '\0'; - setvar("REPLY", buffer); + params->setvar("REPLY", buffer); } ret: -- cgit v1.1