1108639Stjr/*-
2108639Stjr * Copyright (c) 2003 Tim J. Robbins
3108639Stjr * All rights reserved.
4108639Stjr *
5108639Stjr * Redistribution and use in source and binary forms, with or without
6108639Stjr * modification, are permitted provided that the following conditions
7108639Stjr * are met:
8108639Stjr * 1. Redistributions of source code must retain the above copyright
9108639Stjr *    notice, this list of conditions and the following disclaimer.
10108639Stjr * 2. Redistributions in binary form must reproduce the above copyright
11108639Stjr *    notice, this list of conditions and the following disclaimer in the
12108639Stjr *    documentation and/or other materials provided with the distribution.
13108639Stjr *
14108639Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15108639Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16108639Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17108639Stjr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18108639Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19108639Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20108639Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21108639Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22108639Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23108639Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24108639Stjr * SUCH DAMAGE.
25108639Stjr */
26108639Stjr
27108639Stjr/*
28108639Stjr * Test program for wordexp() and wordfree() as specified by
29108639Stjr * IEEE Std. 1003.1-2001.
30108639Stjr */
31108639Stjr
32108639Stjr#include <sys/cdefs.h>
33108639Stjr__FBSDID("$FreeBSD: releng/10.2/tools/regression/lib/libc/gen/test-wordexp.c 281742 2015-04-19 13:46:13Z jilles $");
34108639Stjr
35198406Sjilles#include <sys/wait.h>
36198406Sjilles
37108639Stjr#include <assert.h>
38198406Sjilles#include <errno.h>
39198406Sjilles#include <signal.h>
40108639Stjr#include <stdio.h>
41108639Stjr#include <stdlib.h>
42108639Stjr#include <string.h>
43108639Stjr#include <wordexp.h>
44108639Stjr
45198406Sjillesstatic void
46198406Sjilleschld_handler(int x)
47198406Sjilles{
48198406Sjilles	int status, serrno;
49198406Sjilles
50198406Sjilles	(void)x;
51198406Sjilles	serrno = errno;
52198406Sjilles	while (waitpid(-1, &status, WNOHANG) > 0)
53198406Sjilles		;
54198406Sjilles	errno = serrno;
55198406Sjilles}
56198406Sjilles
57108639Stjrint
58108639Stjrmain(int argc, char *argv[])
59108639Stjr{
60198406Sjilles	struct sigaction sa;
61108639Stjr	wordexp_t we;
62108639Stjr	int r;
63198406Sjilles	int i;
64198406Sjilles	char longdata[6 * 10000 + 1];
65108639Stjr
66108639Stjr	/* Test that the macros are there. */
67174692Sdas	(void)(WRDE_APPEND + WRDE_DOOFFS + WRDE_NOCMD + WRDE_REUSE +
68108639Stjr	    WRDE_SHOWERR + WRDE_UNDEF);
69108639Stjr	(void)(WRDE_BADCHAR + WRDE_BADVAL + WRDE_CMDSUB + WRDE_NOSPACE +
70108639Stjr	    WRDE_SYNTAX);
71108639Stjr
72108639Stjr	/* Simple test. */
73108639Stjr	r = wordexp("hello world", &we, 0);
74108639Stjr	assert(r == 0);
75108639Stjr	assert(we.we_wordc == 2);
76108639Stjr	assert(strcmp(we.we_wordv[0], "hello") == 0);
77108639Stjr	assert(strcmp(we.we_wordv[1], "world") == 0);
78108639Stjr	assert(we.we_wordv[2] == NULL);
79108639Stjr	wordfree(&we);
80108639Stjr
81198406Sjilles	/* Long output. */
82198406Sjilles	for (i = 0; i < 10000; i++)
83198406Sjilles		snprintf(longdata + 6 * i, 7, "%05d ", i);
84198406Sjilles	r = wordexp(longdata, &we, 0);
85198406Sjilles	assert(r == 0);
86198406Sjilles	assert(we.we_wordc == 10000);
87198406Sjilles	assert(we.we_wordv[10000] == NULL);
88198406Sjilles	wordfree(&we);
89198406Sjilles
90174692Sdas	/* WRDE_DOOFFS */
91108639Stjr	we.we_offs = 3;
92174692Sdas	r = wordexp("hello world", &we, WRDE_DOOFFS);
93108639Stjr	assert(r == 0);
94108639Stjr	assert(we.we_wordc == 2);
95108639Stjr	assert(we.we_wordv[0] == NULL);
96108639Stjr	assert(we.we_wordv[1] == NULL);
97108639Stjr	assert(we.we_wordv[2] == NULL);
98108639Stjr	assert(strcmp(we.we_wordv[3], "hello") == 0);
99108639Stjr	assert(strcmp(we.we_wordv[4], "world") == 0);
100108639Stjr	assert(we.we_wordv[5] == NULL);
101108639Stjr	wordfree(&we);
102108639Stjr
103108639Stjr	/* WRDE_REUSE */
104108639Stjr	r = wordexp("hello world", &we, 0);
105108639Stjr	r = wordexp("hello world", &we, WRDE_REUSE);
106108639Stjr	assert(r == 0);
107108639Stjr	assert(we.we_wordc == 2);
108108639Stjr	assert(strcmp(we.we_wordv[0], "hello") == 0);
109108639Stjr	assert(strcmp(we.we_wordv[1], "world") == 0);
110108639Stjr	assert(we.we_wordv[2] == NULL);
111108639Stjr	wordfree(&we);
112108639Stjr
113108639Stjr	/* WRDE_APPEND */
114108639Stjr	r = wordexp("this is", &we, 0);
115108639Stjr	assert(r == 0);
116108639Stjr	r = wordexp("a test", &we, WRDE_APPEND);
117108639Stjr	assert(r == 0);
118108639Stjr	assert(we.we_wordc == 4);
119108639Stjr	assert(strcmp(we.we_wordv[0], "this") == 0);
120108639Stjr	assert(strcmp(we.we_wordv[1], "is") == 0);
121108639Stjr	assert(strcmp(we.we_wordv[2], "a") == 0);
122108639Stjr	assert(strcmp(we.we_wordv[3], "test") == 0);
123108639Stjr	assert(we.we_wordv[4] == NULL);
124108639Stjr	wordfree(&we);
125108639Stjr
126174692Sdas	/* WRDE_DOOFFS + WRDE_APPEND */
127108639Stjr	we.we_offs = 2;
128174692Sdas	r = wordexp("this is", &we, WRDE_DOOFFS);
129108639Stjr	assert(r == 0);
130174692Sdas	r = wordexp("a test", &we, WRDE_APPEND|WRDE_DOOFFS);
131108639Stjr	assert(r == 0);
132174692Sdas	r = wordexp("of wordexp", &we, WRDE_APPEND|WRDE_DOOFFS);
133108639Stjr	assert(r == 0);
134108639Stjr	assert(we.we_wordc == 6);
135108639Stjr	assert(we.we_wordv[0] == NULL);
136108639Stjr	assert(we.we_wordv[1] == NULL);
137108639Stjr	assert(strcmp(we.we_wordv[2], "this") == 0);
138108639Stjr	assert(strcmp(we.we_wordv[3], "is") == 0);
139108639Stjr	assert(strcmp(we.we_wordv[4], "a") == 0);
140108639Stjr	assert(strcmp(we.we_wordv[5], "test") == 0);
141108639Stjr	assert(strcmp(we.we_wordv[6], "of") == 0);
142108639Stjr	assert(strcmp(we.we_wordv[7], "wordexp") == 0);
143108639Stjr	assert(we.we_wordv[8] == NULL);
144108639Stjr	wordfree(&we);
145108639Stjr
146108639Stjr	/* WRDE_UNDEF */
147108639Stjr	r = wordexp("${dont_set_me}", &we, WRDE_UNDEF);
148108639Stjr	assert(r == WRDE_BADVAL);
149108639Stjr
150108639Stjr	/* WRDE_NOCMD */
151108639Stjr	r = wordexp("`date`", &we, WRDE_NOCMD);
152108639Stjr	assert(r == WRDE_CMDSUB);
153108639Stjr	r = wordexp("\"`date`\"", &we, WRDE_NOCMD);
154108639Stjr	assert(r == WRDE_CMDSUB);
155108639Stjr	r = wordexp("$(date)", &we, WRDE_NOCMD);
156108639Stjr	assert(r == WRDE_CMDSUB);
157108639Stjr	r = wordexp("\"$(date)\"", &we, WRDE_NOCMD);
158108639Stjr	assert(r == WRDE_CMDSUB);
159108639Stjr	r = wordexp("$((3+5))", &we, WRDE_NOCMD);
160108639Stjr	assert(r == 0);
161108639Stjr	r = wordexp("\\$\\(date\\)", &we, WRDE_NOCMD|WRDE_REUSE);
162108639Stjr	assert(r == 0);
163108639Stjr	r = wordexp("'`date`'", &we, WRDE_NOCMD|WRDE_REUSE);
164108639Stjr	assert(r == 0);
165108639Stjr	r = wordexp("'$(date)'", &we, WRDE_NOCMD|WRDE_REUSE);
166108639Stjr	assert(r == 0);
167108639Stjr	wordfree(&we);
168108639Stjr
169108639Stjr	/* WRDE_BADCHAR */
170108639Stjr	r = wordexp("'\n|&;<>(){}'", &we, 0);
171108639Stjr	assert(r == 0);
172108639Stjr	r = wordexp("\"\n|&;<>(){}\"", &we, WRDE_REUSE);
173108639Stjr	assert(r == 0);
174108639Stjr	r = wordexp("\\\n\\|\\&\\;\\<\\>\\(\\)\\{\\}", &we, WRDE_REUSE);
175108639Stjr	assert(r == 0);
176108639Stjr	wordfree(&we);
177108639Stjr	r = wordexp("test \n test", &we, 0);
178108639Stjr	assert(r == WRDE_BADCHAR);
179108639Stjr	r = wordexp("test | test", &we, 0);
180108639Stjr	assert(r == WRDE_BADCHAR);
181108639Stjr	r = wordexp("test & test", &we, 0);
182108639Stjr	assert(r == WRDE_BADCHAR);
183108639Stjr	r = wordexp("test ; test", &we, 0);
184108639Stjr	assert(r == WRDE_BADCHAR);
185108639Stjr	r = wordexp("test > test", &we, 0);
186108639Stjr	assert(r == WRDE_BADCHAR);
187108639Stjr	r = wordexp("test < test", &we, 0);
188108639Stjr	assert(r == WRDE_BADCHAR);
189108639Stjr	r = wordexp("test ( test", &we, 0);
190108639Stjr	assert(r == WRDE_BADCHAR);
191108639Stjr	r = wordexp("test ) test", &we, 0);
192108639Stjr	assert(r == WRDE_BADCHAR);
193108639Stjr	r = wordexp("test { test", &we, 0);
194108639Stjr	assert(r == WRDE_BADCHAR);
195108639Stjr	r = wordexp("test } test", &we, 0);
196108639Stjr	assert(r == WRDE_BADCHAR);
197108639Stjr
198253581Sjilles	/* WRDE_SYNTAX */
199253581Sjilles	r = wordexp("'", &we, 0);
200253581Sjilles	assert(r == WRDE_SYNTAX);
201253581Sjilles	r = wordexp("'", &we, WRDE_UNDEF);
202253581Sjilles	assert(r == WRDE_SYNTAX);
203253581Sjilles	r = wordexp("'\\'", &we, 0);
204253581Sjilles	assert(r == 0);
205253581Sjilles	assert(we.we_wordc == 1);
206253581Sjilles	assert(strcmp(we.we_wordv[0], "\\") == 0);
207253581Sjilles	assert(we.we_wordv[1] == NULL);
208253581Sjilles	wordfree(&we);
209253581Sjilles
210198406Sjilles	/* With a SIGCHLD handler that reaps all zombies. */
211198406Sjilles	sa.sa_flags = 0;
212198406Sjilles	sigemptyset(&sa.sa_mask);
213198406Sjilles	sa.sa_handler = chld_handler;
214198406Sjilles	r = sigaction(SIGCHLD, &sa, NULL);
215198406Sjilles	assert(r == 0);
216198406Sjilles	r = wordexp("hello world", &we, 0);
217198406Sjilles	assert(r == 0);
218198406Sjilles	assert(we.we_wordc == 2);
219198406Sjilles	assert(strcmp(we.we_wordv[0], "hello") == 0);
220198406Sjilles	assert(strcmp(we.we_wordv[1], "world") == 0);
221198406Sjilles	assert(we.we_wordv[2] == NULL);
222198406Sjilles	wordfree(&we);
223248987Sjilles	sa.sa_handler = SIG_DFL;
224248987Sjilles	r = sigaction(SIGCHLD, &sa, NULL);
225248987Sjilles	assert(r == 0);
226198406Sjilles
227248987Sjilles	/*
228248987Sjilles	 * With IFS set to a non-default value (without depending on whether
229248987Sjilles	 * IFS is inherited or not).
230248987Sjilles	 */
231248987Sjilles	r = setenv("IFS", ":", 1);
232248987Sjilles	assert(r == 0);
233248987Sjilles	r = wordexp("hello world", &we, 0);
234248987Sjilles	assert(r == 0);
235248987Sjilles	assert(we.we_wordc == 2);
236248987Sjilles	assert(strcmp(we.we_wordv[0], "hello") == 0);
237248987Sjilles	assert(strcmp(we.we_wordv[1], "world") == 0);
238248987Sjilles	assert(we.we_wordv[2] == NULL);
239248987Sjilles	wordfree(&we);
240248987Sjilles	r = unsetenv("IFS");
241248987Sjilles	assert(r == 0);
242248987Sjilles
243281742Sjilles	/*
244281742Sjilles	 * With IFS set to a non-default value, and using it.
245281742Sjilles	 */
246281742Sjilles	r = setenv("IFS", ":", 1);
247281742Sjilles	assert(r == 0);
248281742Sjilles	r = wordexp("${IFS+hello:world}", &we, 0);
249281742Sjilles	assert(r == 0);
250281742Sjilles	assert(we.we_wordc == 2);
251281742Sjilles	assert(strcmp(we.we_wordv[0], "hello") == 0);
252281742Sjilles	assert(strcmp(we.we_wordv[1], "world") == 0);
253281742Sjilles	assert(we.we_wordv[2] == NULL);
254281742Sjilles	wordfree(&we);
255281742Sjilles	r = unsetenv("IFS");
256281742Sjilles	assert(r == 0);
257281742Sjilles
258108639Stjr	printf("PASS wordexp()\n");
259108639Stjr	printf("PASS wordfree()\n");
260108639Stjr
261108639Stjr	return (0);
262108639Stjr}
263