summaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-03-16 18:30:44 +0000
committerUlrich Drepper <drepper@redhat.com>1998-03-16 18:30:44 +0000
commit22bc79788225fb13ff8e66d38e0dd92d44b1e588 (patch)
tree4245a0b22a3abc3601bc9924b5d3452dba61e7c8 /posix
parent6760028826b40e45fe7f12b3e1ec934b032dba55 (diff)
Update.
1998-03-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * posix/wordexp-test.c: Add more tests. (testit): Fix logic. * posix/wordexp.c (exec_comm): In the child, redirect stderr to /dev/null instead of closing it, close pipe. Always chop off all trailing newlines. Kill and reap child before returning error. (w_addword, parse_glob): Fix memory leak. (wordexp): Fix dangling pointer problem. 1998-03-16 Ulrich Drepper <drepper@cygnus.com> * elf/dl-close.c (_dl_close): Correct and simplify unmapping. * posix/wordexp-test.c (main): Fix little thinkos and typos. * catgets/Makefile (CPPFLAGS): Change NLSPATH to also examine directory index by only the language.
Diffstat (limited to 'posix')
-rw-r--r--posix/wordexp-test.c16
-rw-r--r--posix/wordexp.c62
2 files changed, 58 insertions, 20 deletions
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index b8a83c5211..2fc5f0ffac 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -47,6 +47,9 @@ struct test_case_struct
/* Simple parameter expansion */
{ 0, "foo", "${var}", 0, 1, { "foo", } },
{ 0, "foo", "$var", 0, 1, { "foo", } },
+ { 0, "foo", "\\\"$var\\\"", 0, 1, { "\"foo\"", } },
+ { 0, "foo", "%$var%", 0, 1, { "%foo%", } },
+ { 0, "foo", "-$var-", 0, 1, { "-foo-", } },
/* Simple quote removal */
{ 0, NULL, "\"quoted\"", 0, 1, { "quoted", } },
@@ -58,12 +61,15 @@ struct test_case_struct
{ 0, NULL, "$( (echo hello) )", 0, 1, { "hello", } },
{ 0, NULL, "$((echo hello);(echo there))", 0, 2, { "hello", "there", } },
{ 0, NULL, "`echo one two`", 0, 2, { "one", "two", } },
+ { 0, NULL, "$(echo ')')", 0, 1, { ")" } },
+ { 0, NULL, "$(echo hello; echo)", 0, 1, { "hello", } },
/* Simple arithmetic expansion */
{ 0, NULL, "$((1 + 1))", 0, 1, { "2", } },
{ 0, NULL, "$((2-3))", 0, 1, { "-1", } },
{ 0, NULL, "$((-1))", 0, 1, { "-1", } },
{ 0, NULL, "$[50+20]", 0, 1, { "70", } },
+ { 0, NULL, "$(((2+3)*(4+5)))", 0, 1, { "45", } },
/* Advanced parameter expansion */
{ 0, NULL, "${var:-bar}", 0, 1, { "bar", } },
@@ -83,11 +89,14 @@ struct test_case_struct
{ 0, "foo", "${var:+bar}", 0, 1, { "bar", } },
{ 0, "", "${var+bar}", 0, 1, { "bar", } },
{ 0, "12345", "${#var}", 0, 1, { "5", } },
+ { 0, NULL, "${var:-'}'}", 0, 1, { "}", } },
+ { 0, NULL, "${var-}", 0, 0, { NULL } },
{ 0, "banana", "${var%na*}", 0, 1, { "bana", } },
{ 0, "banana", "${var%%na*}", 0, 1, { "ba", } },
{ 0, "borabora-island", "${var#*bora}", 0, 1, { "bora-island", } },
{ 0, "borabora-island", "${var##*bora}", 0, 1, {"-island", } },
+ { 0, "100%", "${var%0%}", 0, 1, { "10" } },
/* Pathname expansion */
{ 0, NULL, "???", 0, 2, { "one", "two", } },
@@ -155,6 +164,7 @@ main (int argc, char *argv[])
const char *globfile[] = { "one", "two", "three", NULL };
char tmpdir[32];
struct passwd *pw;
+ char *cwd;
int test;
int fail = 0;
int i;
@@ -206,8 +216,8 @@ main (int argc, char *argv[])
for (i = 0; globfile[i]; ++i)
remove (globfile[i]);
- if (cwd = NULL)
- strcpy (cwd, "..");
+ if (cwd == NULL)
+ cwd = "..";
chdir (cwd);
rmdir (tmpdir);
@@ -233,7 +243,7 @@ testit (struct test_case_struct *tc)
printf ("Test %d: ", ++test);
retval = wordexp (tc->words, &we, tc->flags);
- if (retval != tc->retval || (retval != 0 && we.we_wordc != tc->wordc))
+ if (retval != tc->retval || (retval == 0 && we.we_wordc != tc->wordc))
bzzzt = 1;
else
for (i = 0; i < we.we_wordc; ++i)
diff --git a/posix/wordexp.c b/posix/wordexp.c
index 5e0e985006..443dc4697d 100644
--- a/posix/wordexp.c
+++ b/posix/wordexp.c
@@ -63,6 +63,11 @@ static int parse_backtick (char **word, size_t *word_length,
size_t *offset, int flags, wordexp_t *pwordexp,
const char *ifs, const char *ifs_white)
internal_function;
+static int parse_dquote (char **word, size_t *word_length, size_t *max_length,
+ const char *words, size_t *offset, int flags,
+ wordexp_t *pwordexp, const char *ifs,
+ const char *ifs_white)
+ internal_function;
static int eval_expr (char *expr, long int *result) internal_function;
/* The w_*() functions manipulate word lists. */
@@ -145,11 +150,13 @@ w_addword (wordexp_t *pwordexp, char *word)
{
/* Add a word to the wordlist */
size_t num_p;
+ char **new_wordv;
num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
- pwordexp->we_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
- if (pwordexp->we_wordv != NULL)
+ new_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
+ if (new_wordv != NULL)
{
+ pwordexp->we_wordv = new_wordv;
pwordexp->we_wordv[pwordexp->we_wordc++] = word;
pwordexp->we_wordv[pwordexp->we_wordc] = NULL;
return 0;
@@ -418,9 +425,13 @@ parse_glob (char **word, size_t *word_length, size_t *max_length,
{
/* No field splitting allowed */
size_t length = strlen (globbuf.gl_pathv[0]);
+ char *old_word = *word;
*word = realloc (*word, length + 1);
if (*word == NULL)
- goto no_space;
+ {
+ free (old_word);
+ goto no_space;
+ }
memcpy (*word, globbuf.gl_pathv[0], length + 1);
*word_length = length;
@@ -792,13 +803,24 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
/* Child */
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
- /* Redirect input and output */
+ /* Redirect output. */
dup2 (fildes[1], 1);
+ close (fildes[1]);
- /* Close stderr if we have to */
+ /* Redirect stderr to /dev/null if we have to. */
if ((flags & WRDE_SHOWERR) == 0)
- close (2);
+ {
+ int fd;
+ close (2);
+ fd = open (_PATH_DEVNULL, O_WRONLY);
+ if (fd >= 0 && fd != 2)
+ {
+ dup2 (fd, 2);
+ close (fd);
+ }
+ }
+ close (fildes[0]);
__execve (_PATH_BSHELL, (char *const *) args, __environ);
/* Bad. What now? */
@@ -826,18 +848,12 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
*word = w_addmem (*word, word_length, max_length, buffer, buflen);
if (*word == NULL)
{
+ kill (pid, SIGKILL);
+ __waitpid (pid, NULL, 0);
close (fildes[0]);
return WRDE_NOSPACE;
}
}
-
- close (fildes[0]);
-
- /* bash chops off a terminating linefeed, which seems sensible */
- if ((*word)[*word_length - 1] == '\n')
- (*word)[--*word_length] = '\0';
-
- return 0;
}
else
/* Not quoted - split fields */
@@ -903,6 +919,8 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
*word = w_addchar (*word, word_length, max_length, 0);
if (*word == NULL)
{
+ kill (pid, SIGKILL);
+ __waitpid (pid, NULL, 0);
close (fildes[0]);
return WRDE_NOSPACE;
}
@@ -910,7 +928,8 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
{
- /* Should do __waitpid? */
+ kill (pid, SIGKILL);
+ __waitpid (pid, NULL, 0);
close (fildes[0]);
return WRDE_NOSPACE;
}
@@ -928,6 +947,8 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
buffer[i]);
if (*word == NULL)
{
+ kill (pid, SIGKILL);
+ __waitpid (pid, NULL, 0);
close (fildes[0]);
return WRDE_NOSPACE;
}
@@ -936,6 +957,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
}
}
+ /* Bash chops off trailing newlines, which seems sensible. */
+ while (*word_length > 0 && (*word)[*word_length - 1] == '\n')
+ (*word)[--*word_length] = '\0';
+
close (fildes[0]);
return 0;
}
@@ -1991,8 +2016,11 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
size_t old_wordc = (flags & WRDE_REUSE) ? pwordexp->we_wordc : 0;
if (flags & WRDE_REUSE)
- /* Minimal implementation of WRDE_REUSE for now */
- wordfree (pwordexp);
+ {
+ /* Minimal implementation of WRDE_REUSE for now */
+ wordfree (pwordexp);
+ old_wordv = NULL;
+ }
if (flags & WRDE_DOOFFS)
{