ash: implement -d DELIM option for read

The POSIX standard only requires the read builtin to handle -r:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html

However, Bash introduced the option -d <DELIM> to override IFS for
just one invocation, and it is quite useful.

It is also super easy to implement in BusyBox' ash, so let's do that.

The motivation: This option is used by Git's test suite.

function                                             old     new   delta
.rodata                                           163505  163587     +82
shell_builtin_read                                  1244    1289     +45
readcmd                                              233     259     +26
builtin_read                                         258     263      +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 158/0)             Total: 158 bytes

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Johannes Schindelin 2017-08-08 16:46:39 +02:00 committed by Denys Vlasenko
parent 5856dc74be
commit 3bef5d89b0
3 changed files with 21 additions and 7 deletions

View file

@ -54,7 +54,8 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
const char *opt_n,
const char *opt_p,
const char *opt_t,
const char *opt_u
const char *opt_u,
const char *opt_d
)
{
struct pollfd pfd[1];
@ -237,14 +238,17 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
continue;
}
}
if (c == '\n')
if (opt_d) {
if (c == *opt_d)
break;
} else if (c == '\n')
break;
/* $IFS splitting. NOT done if we run "read"
* without variable names (bash compat).
* Thus, "read" and "read REPLY" are not the same.
*/
if (argv[0]) {
if (!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) {