mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
wordexp(): Improve some error codes.
Distinguish between WRDE_BADVAL and WRDE_SYNTAX based on when the error occurred (parsing or execution), not based on whether WRDE_UNDEF was passed. Also, return WRDE_NOSPACE for a few more unexpected results from sh.
This commit is contained in:
parent
b38fbc2e54
commit
89cead337a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286941
@ -131,9 +131,10 @@ argument contains one of the following unquoted characters:
|
||||
.Ql { ,
|
||||
.Ql } .
|
||||
.It Dv WRDE_BADVAL
|
||||
An attempt was made to expand an undefined shell variable and
|
||||
An error after successful parsing,
|
||||
such as an attempt to expand an undefined shell variable with
|
||||
.Dv WRDE_UNDEF
|
||||
is set in
|
||||
set in
|
||||
.Fa flags .
|
||||
.It Dv WRDE_CMDSUB
|
||||
An attempt was made to use command substitution and
|
||||
@ -141,7 +142,9 @@ An attempt was made to use command substitution and
|
||||
is set in
|
||||
.Fa flags .
|
||||
.It Dv WRDE_NOSPACE
|
||||
Not enough memory to store the result.
|
||||
Not enough memory to store the result or
|
||||
an error during
|
||||
.Xr fork 2 .
|
||||
.It Dv WRDE_SYNTAX
|
||||
Shell syntax error in
|
||||
.Fa words .
|
||||
|
@ -103,8 +103,7 @@ static int
|
||||
we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
{
|
||||
int pdes[2]; /* Pipe to child */
|
||||
char bbuf[9]; /* Buffer for byte count */
|
||||
char wbuf[9]; /* Buffer for word count */
|
||||
char buf[18]; /* Buffer for byte and word count */
|
||||
long nwords, nbytes; /* Number of words, bytes from child */
|
||||
long i; /* Handy integer */
|
||||
size_t sofs; /* Offset into we->we_strings */
|
||||
@ -119,6 +118,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
char **nwv; /* Temporary for realloc() */
|
||||
sigset_t newsigblock, oldsigblock;
|
||||
const char *ifs;
|
||||
char save;
|
||||
|
||||
serrno = errno;
|
||||
ifs = getenv("IFS");
|
||||
@ -146,8 +146,9 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
_fcntl(pdes[1], F_SETFD, 0)) < 0)
|
||||
_exit(1);
|
||||
execl(_PATH_BSHELL, "sh", flags & WRDE_UNDEF ? "-u" : "+u",
|
||||
"-c", "IFS=$1;eval \"$2\";eval \"set -- $3\";IFS=;a=\"$*\";"
|
||||
"printf '%08x' \"$#\" \"${#a}\";printf '%s\\0' \"$@\"",
|
||||
"-c", "IFS=$1;eval \"$2\";eval \"echo;set -- $3\";"
|
||||
"IFS=;a=\"$*\";printf '%08x' \"$#\" \"${#a}\";"
|
||||
"printf '%s\\0' \"$@\"",
|
||||
"",
|
||||
ifs != NULL ? ifs : " \t\n",
|
||||
flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", words,
|
||||
@ -157,20 +158,30 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
|
||||
/*
|
||||
* We are the parent; read the output of the shell wordexp function,
|
||||
* which is a 32-bit hexadecimal word count, a 32-bit hexadecimal
|
||||
* byte count (not including terminating null bytes), followed by
|
||||
* the expanded words separated by nulls.
|
||||
* which is a byte indicating that the words were parsed successfully,
|
||||
* a 32-bit hexadecimal word count, a 32-bit hexadecimal byte count
|
||||
* (not including terminating null bytes), followed by the expanded
|
||||
* words separated by nulls.
|
||||
*/
|
||||
_close(pdes[1]);
|
||||
if (we_read_fully(pdes[0], wbuf, 8) != 8 ||
|
||||
we_read_fully(pdes[0], bbuf, 8) != 8) {
|
||||
error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX;
|
||||
switch (we_read_fully(pdes[0], buf, 17)) {
|
||||
case 1:
|
||||
error = WRDE_BADVAL;
|
||||
serrno = errno;
|
||||
goto cleanup;
|
||||
case 17:
|
||||
break;
|
||||
default:
|
||||
error = WRDE_SYNTAX;
|
||||
serrno = errno;
|
||||
goto cleanup;
|
||||
}
|
||||
wbuf[8] = bbuf[8] = '\0';
|
||||
nwords = strtol(wbuf, NULL, 16);
|
||||
nbytes = strtol(bbuf, NULL, 16) + nwords;
|
||||
save = buf[9];
|
||||
buf[9] = '\0';
|
||||
nwords = strtol(buf + 1, NULL, 16);
|
||||
buf[9] = save;
|
||||
buf[17] = '\0';
|
||||
nbytes = strtol(buf + 9, NULL, 16) + nwords;
|
||||
|
||||
/*
|
||||
* Allocate or reallocate (when flags & WRDE_APPEND) the word vector
|
||||
@ -200,7 +211,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
we->we_strings = nstrings;
|
||||
|
||||
if (we_read_fully(pdes[0], we->we_strings + sofs, nbytes) != nbytes) {
|
||||
error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX;
|
||||
error = WRDE_NOSPACE; /* abort for unknown reason */
|
||||
serrno = errno;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -217,7 +228,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
return (error);
|
||||
}
|
||||
if (wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
|
||||
return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX);
|
||||
return (WRDE_NOSPACE); /* abort for unknown reason */
|
||||
|
||||
/*
|
||||
* Break the null-terminated expanded word strings out into
|
||||
|
@ -206,6 +206,15 @@ main(int argc, char *argv[])
|
||||
assert(strcmp(we.we_wordv[0], "\\") == 0);
|
||||
assert(we.we_wordv[1] == NULL);
|
||||
wordfree(&we);
|
||||
/* Two syntax errors that are not detected by the current we_check(). */
|
||||
r = wordexp("${IFS:+'}", &we, 0);
|
||||
assert(r == WRDE_SYNTAX);
|
||||
r = wordexp("${IFS:+'}", &we, WRDE_UNDEF);
|
||||
assert(r == WRDE_SYNTAX);
|
||||
r = wordexp("$(case)", &we, 0);
|
||||
assert(r == WRDE_SYNTAX);
|
||||
r = wordexp("$(case)", &we, WRDE_UNDEF);
|
||||
assert(r == WRDE_SYNTAX);
|
||||
|
||||
/* With a SIGCHLD handler that reaps all zombies. */
|
||||
sa.sa_flags = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user