ash: remove limitation on fd# length
"echo text >&0000000000002" works as you would expect, "echo text >&9999999999" properly fails instead of creating a file named "9999999999". function old new delta expredir 219 232 +13 readtoken1 3045 3053 +8 parsefname 204 201 -3 isdigit_str9 45 - -45 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 2/1 up/down: 21/-48) Total: -27 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0829fce079
commit
08fb86726b
1 changed files with 13 additions and 7 deletions
20
shell/ash.c
20
shell/ash.c
|
@ -557,10 +557,9 @@ static void trace_vprintf(const char *fmt, va_list va);
|
||||||
#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
|
#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isdigit_str9(const char *str)
|
isdigit_str(const char *str)
|
||||||
{
|
{
|
||||||
int maxlen = 9 + 1; /* max 9 digits: 999999999 */
|
while (isdigit(*str))
|
||||||
while (--maxlen && isdigit(*str))
|
|
||||||
str++;
|
str++;
|
||||||
return (*str == '\0');
|
return (*str == '\0');
|
||||||
}
|
}
|
||||||
|
@ -9661,7 +9660,7 @@ expredir(union node *n)
|
||||||
if (fn.list == NULL)
|
if (fn.list == NULL)
|
||||||
ash_msg_and_raise_error("redir error");
|
ash_msg_and_raise_error("redir error");
|
||||||
#if BASH_REDIR_OUTPUT
|
#if BASH_REDIR_OUTPUT
|
||||||
if (!isdigit_str9(fn.list->text)) {
|
if (!isdigit_str(fn.list->text)) {
|
||||||
/* >&file, not >&fd */
|
/* >&file, not >&fd */
|
||||||
if (redir->nfile.fd != 1) /* 123>&file - BAD */
|
if (redir->nfile.fd != 1) /* 123>&file - BAD */
|
||||||
ash_msg_and_raise_error("redir error");
|
ash_msg_and_raise_error("redir error");
|
||||||
|
@ -12011,12 +12010,19 @@ fixredir(union node *n, const char *text, int err)
|
||||||
if (!err)
|
if (!err)
|
||||||
n->ndup.vname = NULL;
|
n->ndup.vname = NULL;
|
||||||
|
|
||||||
|
if (LONE_DASH(text)) {
|
||||||
|
n->ndup.dupfd = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fd = bb_strtou(text, NULL, 10);
|
fd = bb_strtou(text, NULL, 10);
|
||||||
if (!errno && fd >= 0)
|
if (!errno && fd >= 0)
|
||||||
n->ndup.dupfd = fd;
|
n->ndup.dupfd = fd;
|
||||||
else if (LONE_DASH(text))
|
|
||||||
n->ndup.dupfd = -1;
|
|
||||||
else {
|
else {
|
||||||
|
/* This also fails on very large numbers
|
||||||
|
* which overflow "int" - bb_strtou() does not
|
||||||
|
* silently truncate results to word width.
|
||||||
|
*/
|
||||||
if (err)
|
if (err)
|
||||||
raise_error_syntax("bad fd number");
|
raise_error_syntax("bad fd number");
|
||||||
n->ndup.vname = makename();
|
n->ndup.vname = makename();
|
||||||
|
@ -12702,7 +12708,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||||
if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
|
if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
|
||||||
&& quotef == 0
|
&& quotef == 0
|
||||||
) {
|
) {
|
||||||
if (isdigit_str9(out)) {
|
if (isdigit_str(out)) {
|
||||||
PARSEREDIR(); /* passed as params: out, c */
|
PARSEREDIR(); /* passed as params: out, c */
|
||||||
lasttoken = TREDIR;
|
lasttoken = TREDIR;
|
||||||
return lasttoken;
|
return lasttoken;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue