diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | catgets/Makefile | 4 | ||||
-rw-r--r-- | elf/dl-close.c | 30 | ||||
-rw-r--r-- | posix/wordexp-test.c | 16 | ||||
-rw-r--r-- | posix/wordexp.c | 62 |
5 files changed, 95 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog index 7c0236f192..31b91d2a4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +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. + 1998-03-16 13:02 Tim Waugh <tim@cyberelk.demon.co.uk> * posix/wordexp-tst.sh: Store test results in the diff --git a/catgets/Makefile b/catgets/Makefile index 0631599f18..ee464c1adc 100644 --- a/catgets/Makefile +++ b/catgets/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -38,5 +38,5 @@ include ../Rules $(objpfx)gencat: $(gencat-modules:%=$(objpfx)%.o) -CPPFLAGS := -DNLSPATH='"$(localedir)/%L/%N:$(localedir)/%L/LC_MESSAGES/%N:"' \ +CPPFLAGS := -DNLSPATH='"$(localedir)/%L/%N:$(localedir)/%L/LC_MESSAGES/%N:$(localedir)/%l/%N:$(localedir)/%l/LC_MESSAGES/%N:"' \ -DHAVE_CONFIG_H $(CPPFLAGS) diff --git a/elf/dl-close.c b/elf/dl-close.c index 253b073367..f2155031e6 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -80,7 +80,8 @@ _dl_close (struct link_map *map) /* That was the last reference, and this was a dlopen-loaded object. We can unmap it. */ const ElfW(Phdr) *ph; - const ElfW(Phdr) *eph; + const ElfW(Phdr) *first, *last; + ElfW(Addr) mapstart, mapend; if (imap->l_info[DT_FINI]) /* Call its termination function. */ @@ -100,24 +101,23 @@ _dl_close (struct link_map *map) _dl_global_scope_end[1] = NULL; } - /* Find the first entry specifying a load command. We have - to determine this now since the table itself is also loaded. */ - for (eph = imap->l_phdr; eph < imap->l_phdr + imap->l_phnum; ++eph) - if (eph->p_type == PT_LOAD) - break; - - /* Unmap the segments. */ - for (ph = imap->l_phdr + (imap->l_phnum - 1); ph >= eph; --ph) + /* We can unmap all the maps at once. We just have to determine + the length and the `munmap' call does the rest. */ + first = last = NULL; + for (ph = imap->l_phdr; ph < imap->l_phdr + imap->l_phnum; ++ph) if (ph->p_type == PT_LOAD) { - ElfW(Addr) mapstart = ph->p_vaddr & ~(ph->p_align - 1); - ElfW(Addr) mapend = ((ph->p_vaddr + ph->p_memsz - + ph->p_align - 1) - & ~(ph->p_align - 1)); - __munmap ((caddr_t) (imap->l_addr + mapstart), - mapend - mapstart); + if (first == NULL) + first = ph; + last = ph; } + /* Now we have all the information we need for the unmapping. + See the method used in `_dl_map_object_from_fd'. */ + mapstart = first->p_vaddr & ~(first->p_align - 1); + mapend = last->p_vaddr + last->p_memsz; + __munmap ((caddr_t) (imap->l_addr + mapstart), mapend - mapstart); + /* Finally, unlink the data structure and free it. */ if (imap->l_prev) imap->l_prev->l_next = imap->l_next; 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) { |