diff options
author | jilles <jilles@FreeBSD.org> | 2009-10-23 14:50:11 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2009-10-23 14:50:11 +0000 |
commit | 2dcc53599c6a7af58c845d0d3796bcde7e21b437 (patch) | |
tree | 536a76c5ea65f8afdc1489d4092d72ddfa15073f /tools | |
parent | 8f8a90522cbb3bb03782bc7bf40d03dc744c7572 (diff) | |
download | FreeBSD-src-2dcc53599c6a7af58c845d0d3796bcde7e21b437.zip FreeBSD-src-2dcc53599c6a7af58c845d0d3796bcde7e21b437.tar.gz |
wordexp(3): fix some bugs with signals and long outputs
* retry various system calls on EINTR
* retry the rest after a short read (common if there is more than about 1K
of output)
* block SIGCHLD like system(3) does (note that this does not and cannot
work fully in threaded programs, they will need to be careful with wait
functions)
PR: 90580
MFC after: 1 month
Diffstat (limited to 'tools')
-rw-r--r-- | tools/regression/lib/libc/gen/test-wordexp.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/tools/regression/lib/libc/gen/test-wordexp.c b/tools/regression/lib/libc/gen/test-wordexp.c index c78199e..df8f885 100644 --- a/tools/regression/lib/libc/gen/test-wordexp.c +++ b/tools/regression/lib/libc/gen/test-wordexp.c @@ -32,17 +32,36 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/wait.h> + #include <assert.h> +#include <errno.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <wordexp.h> +static void +chld_handler(int x) +{ + int status, serrno; + + (void)x; + serrno = errno; + while (waitpid(-1, &status, WNOHANG) > 0) + ; + errno = serrno; +} + int main(int argc, char *argv[]) { + struct sigaction sa; wordexp_t we; int r; + int i; + char longdata[6 * 10000 + 1]; /* Test that the macros are there. */ (void)(WRDE_APPEND + WRDE_DOOFFS + WRDE_NOCMD + WRDE_REUSE + @@ -59,6 +78,15 @@ main(int argc, char *argv[]) assert(we.we_wordv[2] == NULL); wordfree(&we); + /* Long output. */ + for (i = 0; i < 10000; i++) + snprintf(longdata + 6 * i, 7, "%05d ", i); + r = wordexp(longdata, &we, 0); + assert(r == 0); + assert(we.we_wordc == 10000); + assert(we.we_wordv[10000] == NULL); + wordfree(&we); + /* WRDE_DOOFFS */ we.we_offs = 3; r = wordexp("hello world", &we, WRDE_DOOFFS); @@ -167,6 +195,20 @@ main(int argc, char *argv[]) r = wordexp("test } test", &we, 0); assert(r == WRDE_BADCHAR); + /* With a SIGCHLD handler that reaps all zombies. */ + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sa.sa_handler = chld_handler; + r = sigaction(SIGCHLD, &sa, NULL); + assert(r == 0); + r = wordexp("hello world", &we, 0); + assert(r == 0); + assert(we.we_wordc == 2); + assert(strcmp(we.we_wordv[0], "hello") == 0); + assert(strcmp(we.we_wordv[1], "world") == 0); + assert(we.we_wordv[2] == NULL); + wordfree(&we); + printf("PASS wordexp()\n"); printf("PASS wordfree()\n"); |