Date: Wed, 19 Aug 2015 20:31:04 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286941 - in head: lib/libc/gen tools/regression/lib/libc/gen Message-ID: <201508192031.t7JKV49G028449@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jilles Date: Wed Aug 19 20:31:03 2015 New Revision: 286941 URL: https://svnweb.freebsd.org/changeset/base/286941 Log: 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. Modified: head/lib/libc/gen/wordexp.3 head/lib/libc/gen/wordexp.c head/tools/regression/lib/libc/gen/test-wordexp.c Modified: head/lib/libc/gen/wordexp.3 ============================================================================== --- head/lib/libc/gen/wordexp.3 Wed Aug 19 20:10:58 2015 (r286940) +++ head/lib/libc/gen/wordexp.3 Wed Aug 19 20:31:03 2015 (r286941) @@ -131,9 +131,10 @@ argument contains one of the following u .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 subst 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 . Modified: head/lib/libc/gen/wordexp.c ============================================================================== --- head/lib/libc/gen/wordexp.c Wed Aug 19 20:10:58 2015 (r286940) +++ head/lib/libc/gen/wordexp.c Wed Aug 19 20:31:03 2015 (r286941) @@ -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 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 _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 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->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 @@ cleanup: 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 Modified: head/tools/regression/lib/libc/gen/test-wordexp.c ============================================================================== --- head/tools/regression/lib/libc/gen/test-wordexp.c Wed Aug 19 20:10:58 2015 (r286940) +++ head/tools/regression/lib/libc/gen/test-wordexp.c Wed Aug 19 20:31:03 2015 (r286941) @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508192031.t7JKV49G028449>