mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-24 12:25:35 +08:00
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.
This commit is contained in:
parent
6760028826
commit
22bc797882
20
ChangeLog
20
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>
|
1998-03-16 13:02 Tim Waugh <tim@cyberelk.demon.co.uk>
|
||||||
|
|
||||||
* posix/wordexp-tst.sh: Store test results in the
|
* posix/wordexp-tst.sh: Store test results in the
|
||||||
|
@ -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.
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
# The GNU C Library is free software; you can redistribute it and/or
|
# 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)
|
$(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)
|
-DHAVE_CONFIG_H $(CPPFLAGS)
|
||||||
|
@ -80,7 +80,8 @@ _dl_close (struct link_map *map)
|
|||||||
/* That was the last reference, and this was a dlopen-loaded
|
/* That was the last reference, and this was a dlopen-loaded
|
||||||
object. We can unmap it. */
|
object. We can unmap it. */
|
||||||
const ElfW(Phdr) *ph;
|
const ElfW(Phdr) *ph;
|
||||||
const ElfW(Phdr) *eph;
|
const ElfW(Phdr) *first, *last;
|
||||||
|
ElfW(Addr) mapstart, mapend;
|
||||||
|
|
||||||
if (imap->l_info[DT_FINI])
|
if (imap->l_info[DT_FINI])
|
||||||
/* Call its termination function. */
|
/* Call its termination function. */
|
||||||
@ -100,24 +101,23 @@ _dl_close (struct link_map *map)
|
|||||||
_dl_global_scope_end[1] = NULL;
|
_dl_global_scope_end[1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the first entry specifying a load command. We have
|
/* We can unmap all the maps at once. We just have to determine
|
||||||
to determine this now since the table itself is also loaded. */
|
the length and the `munmap' call does the rest. */
|
||||||
for (eph = imap->l_phdr; eph < imap->l_phdr + imap->l_phnum; ++eph)
|
first = last = NULL;
|
||||||
if (eph->p_type == PT_LOAD)
|
for (ph = imap->l_phdr; ph < imap->l_phdr + imap->l_phnum; ++ph)
|
||||||
break;
|
|
||||||
|
|
||||||
/* Unmap the segments. */
|
|
||||||
for (ph = imap->l_phdr + (imap->l_phnum - 1); ph >= eph; --ph)
|
|
||||||
if (ph->p_type == PT_LOAD)
|
if (ph->p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
ElfW(Addr) mapstart = ph->p_vaddr & ~(ph->p_align - 1);
|
if (first == NULL)
|
||||||
ElfW(Addr) mapend = ((ph->p_vaddr + ph->p_memsz
|
first = ph;
|
||||||
+ ph->p_align - 1)
|
last = ph;
|
||||||
& ~(ph->p_align - 1));
|
|
||||||
__munmap ((caddr_t) (imap->l_addr + mapstart),
|
|
||||||
mapend - mapstart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
/* Finally, unlink the data structure and free it. */
|
||||||
if (imap->l_prev)
|
if (imap->l_prev)
|
||||||
imap->l_prev->l_next = imap->l_next;
|
imap->l_prev->l_next = imap->l_next;
|
||||||
|
@ -47,6 +47,9 @@ struct test_case_struct
|
|||||||
/* Simple parameter expansion */
|
/* 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\"", } },
|
||||||
|
{ 0, "foo", "%$var%", 0, 1, { "%foo%", } },
|
||||||
|
{ 0, "foo", "-$var-", 0, 1, { "-foo-", } },
|
||||||
|
|
||||||
/* Simple quote removal */
|
/* Simple quote removal */
|
||||||
{ 0, NULL, "\"quoted\"", 0, 1, { "quoted", } },
|
{ 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) )", 0, 1, { "hello", } },
|
||||||
{ 0, NULL, "$((echo hello);(echo there))", 0, 2, { "hello", "there", } },
|
{ 0, NULL, "$((echo hello);(echo there))", 0, 2, { "hello", "there", } },
|
||||||
{ 0, NULL, "`echo one two`", 0, 2, { "one", "two", } },
|
{ 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 */
|
/* Simple arithmetic expansion */
|
||||||
{ 0, NULL, "$((1 + 1))", 0, 1, { "2", } },
|
{ 0, NULL, "$((1 + 1))", 0, 1, { "2", } },
|
||||||
{ 0, NULL, "$((2-3))", 0, 1, { "-1", } },
|
{ 0, NULL, "$((2-3))", 0, 1, { "-1", } },
|
||||||
{ 0, NULL, "$((-1))", 0, 1, { "-1", } },
|
{ 0, NULL, "$((-1))", 0, 1, { "-1", } },
|
||||||
{ 0, NULL, "$[50+20]", 0, 1, { "70", } },
|
{ 0, NULL, "$[50+20]", 0, 1, { "70", } },
|
||||||
|
{ 0, NULL, "$(((2+3)*(4+5)))", 0, 1, { "45", } },
|
||||||
|
|
||||||
/* Advanced parameter expansion */
|
/* Advanced parameter expansion */
|
||||||
{ 0, NULL, "${var:-bar}", 0, 1, { "bar", } },
|
{ 0, NULL, "${var:-bar}", 0, 1, { "bar", } },
|
||||||
@ -83,11 +89,14 @@ struct test_case_struct
|
|||||||
{ 0, "foo", "${var:+bar}", 0, 1, { "bar", } },
|
{ 0, "foo", "${var:+bar}", 0, 1, { "bar", } },
|
||||||
{ 0, "", "${var+bar}", 0, 1, { "bar", } },
|
{ 0, "", "${var+bar}", 0, 1, { "bar", } },
|
||||||
{ 0, "12345", "${#var}", 0, 1, { "5", } },
|
{ 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, { "bana", } },
|
||||||
{ 0, "banana", "${var%%na*}", 0, 1, { "ba", } },
|
{ 0, "banana", "${var%%na*}", 0, 1, { "ba", } },
|
||||||
{ 0, "borabora-island", "${var#*bora}", 0, 1, { "bora-island", } },
|
{ 0, "borabora-island", "${var#*bora}", 0, 1, { "bora-island", } },
|
||||||
{ 0, "borabora-island", "${var##*bora}", 0, 1, {"-island", } },
|
{ 0, "borabora-island", "${var##*bora}", 0, 1, {"-island", } },
|
||||||
|
{ 0, "100%", "${var%0%}", 0, 1, { "10" } },
|
||||||
|
|
||||||
/* Pathname expansion */
|
/* Pathname expansion */
|
||||||
{ 0, NULL, "???", 0, 2, { "one", "two", } },
|
{ 0, NULL, "???", 0, 2, { "one", "two", } },
|
||||||
@ -155,6 +164,7 @@ main (int argc, char *argv[])
|
|||||||
const char *globfile[] = { "one", "two", "three", NULL };
|
const char *globfile[] = { "one", "two", "three", NULL };
|
||||||
char tmpdir[32];
|
char tmpdir[32];
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
char *cwd;
|
||||||
int test;
|
int test;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -206,8 +216,8 @@ main (int argc, char *argv[])
|
|||||||
for (i = 0; globfile[i]; ++i)
|
for (i = 0; globfile[i]; ++i)
|
||||||
remove (globfile[i]);
|
remove (globfile[i]);
|
||||||
|
|
||||||
if (cwd = NULL)
|
if (cwd == NULL)
|
||||||
strcpy (cwd, "..");
|
cwd = "..";
|
||||||
|
|
||||||
chdir (cwd);
|
chdir (cwd);
|
||||||
rmdir (tmpdir);
|
rmdir (tmpdir);
|
||||||
@ -233,7 +243,7 @@ testit (struct test_case_struct *tc)
|
|||||||
printf ("Test %d: ", ++test);
|
printf ("Test %d: ", ++test);
|
||||||
retval = wordexp (tc->words, &we, tc->flags);
|
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;
|
bzzzt = 1;
|
||||||
else
|
else
|
||||||
for (i = 0; i < we.we_wordc; ++i)
|
for (i = 0; i < we.we_wordc; ++i)
|
||||||
|
@ -63,6 +63,11 @@ static int parse_backtick (char **word, size_t *word_length,
|
|||||||
size_t *offset, int flags, wordexp_t *pwordexp,
|
size_t *offset, int flags, wordexp_t *pwordexp,
|
||||||
const char *ifs, const char *ifs_white)
|
const char *ifs, const char *ifs_white)
|
||||||
internal_function;
|
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;
|
static int eval_expr (char *expr, long int *result) internal_function;
|
||||||
|
|
||||||
/* The w_*() functions manipulate word lists. */
|
/* The w_*() functions manipulate word lists. */
|
||||||
@ -145,11 +150,13 @@ w_addword (wordexp_t *pwordexp, char *word)
|
|||||||
{
|
{
|
||||||
/* Add a word to the wordlist */
|
/* Add a word to the wordlist */
|
||||||
size_t num_p;
|
size_t num_p;
|
||||||
|
char **new_wordv;
|
||||||
|
|
||||||
num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
|
num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
|
||||||
pwordexp->we_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
|
new_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
|
||||||
if (pwordexp->we_wordv != NULL)
|
if (new_wordv != NULL)
|
||||||
{
|
{
|
||||||
|
pwordexp->we_wordv = new_wordv;
|
||||||
pwordexp->we_wordv[pwordexp->we_wordc++] = word;
|
pwordexp->we_wordv[pwordexp->we_wordc++] = word;
|
||||||
pwordexp->we_wordv[pwordexp->we_wordc] = NULL;
|
pwordexp->we_wordv[pwordexp->we_wordc] = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
@ -418,9 +425,13 @@ parse_glob (char **word, size_t *word_length, size_t *max_length,
|
|||||||
{
|
{
|
||||||
/* No field splitting allowed */
|
/* No field splitting allowed */
|
||||||
size_t length = strlen (globbuf.gl_pathv[0]);
|
size_t length = strlen (globbuf.gl_pathv[0]);
|
||||||
|
char *old_word = *word;
|
||||||
*word = realloc (*word, length + 1);
|
*word = realloc (*word, length + 1);
|
||||||
if (*word == NULL)
|
if (*word == NULL)
|
||||||
goto no_space;
|
{
|
||||||
|
free (old_word);
|
||||||
|
goto no_space;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy (*word, globbuf.gl_pathv[0], length + 1);
|
memcpy (*word, globbuf.gl_pathv[0], length + 1);
|
||||||
*word_length = length;
|
*word_length = length;
|
||||||
@ -792,13 +803,24 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
|||||||
/* Child */
|
/* Child */
|
||||||
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
|
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
|
||||||
|
|
||||||
/* Redirect input and output */
|
/* Redirect output. */
|
||||||
dup2 (fildes[1], 1);
|
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)
|
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);
|
__execve (_PATH_BSHELL, (char *const *) args, __environ);
|
||||||
|
|
||||||
/* Bad. What now? */
|
/* 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);
|
*word = w_addmem (*word, word_length, max_length, buffer, buflen);
|
||||||
if (*word == NULL)
|
if (*word == NULL)
|
||||||
{
|
{
|
||||||
|
kill (pid, SIGKILL);
|
||||||
|
__waitpid (pid, NULL, 0);
|
||||||
close (fildes[0]);
|
close (fildes[0]);
|
||||||
return WRDE_NOSPACE;
|
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
|
else
|
||||||
/* Not quoted - split fields */
|
/* 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);
|
*word = w_addchar (*word, word_length, max_length, 0);
|
||||||
if (*word == NULL)
|
if (*word == NULL)
|
||||||
{
|
{
|
||||||
|
kill (pid, SIGKILL);
|
||||||
|
__waitpid (pid, NULL, 0);
|
||||||
close (fildes[0]);
|
close (fildes[0]);
|
||||||
return WRDE_NOSPACE;
|
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)
|
if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
|
||||||
{
|
{
|
||||||
/* Should do __waitpid? */
|
kill (pid, SIGKILL);
|
||||||
|
__waitpid (pid, NULL, 0);
|
||||||
close (fildes[0]);
|
close (fildes[0]);
|
||||||
return WRDE_NOSPACE;
|
return WRDE_NOSPACE;
|
||||||
}
|
}
|
||||||
@ -928,6 +947,8 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
|||||||
buffer[i]);
|
buffer[i]);
|
||||||
if (*word == NULL)
|
if (*word == NULL)
|
||||||
{
|
{
|
||||||
|
kill (pid, SIGKILL);
|
||||||
|
__waitpid (pid, NULL, 0);
|
||||||
close (fildes[0]);
|
close (fildes[0]);
|
||||||
return WRDE_NOSPACE;
|
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]);
|
close (fildes[0]);
|
||||||
return 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;
|
size_t old_wordc = (flags & WRDE_REUSE) ? pwordexp->we_wordc : 0;
|
||||||
|
|
||||||
if (flags & WRDE_REUSE)
|
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)
|
if (flags & WRDE_DOOFFS)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user