summaryrefslogtreecommitdiffstats
path: root/tools/regression/lib
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2009-10-23 14:50:11 +0000
committerjilles <jilles@FreeBSD.org>2009-10-23 14:50:11 +0000
commit2dcc53599c6a7af58c845d0d3796bcde7e21b437 (patch)
tree536a76c5ea65f8afdc1489d4092d72ddfa15073f /tools/regression/lib
parent8f8a90522cbb3bb03782bc7bf40d03dc744c7572 (diff)
downloadFreeBSD-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/regression/lib')
-rw-r--r--tools/regression/lib/libc/gen/test-wordexp.c42
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");
OpenPOWER on IntegriCloud