test-wordexp.c revision 281742
1/*-
2 * Copyright (c) 2003 Tim J. Robbins
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Test program for wordexp() and wordfree() as specified by
29 * IEEE Std. 1003.1-2001.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: stable/10/tools/regression/lib/libc/gen/test-wordexp.c 281742 2015-04-19 13:46:13Z jilles $");
34
35#include <sys/wait.h>
36
37#include <assert.h>
38#include <errno.h>
39#include <signal.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <wordexp.h>
44
45static void
46chld_handler(int x)
47{
48	int status, serrno;
49
50	(void)x;
51	serrno = errno;
52	while (waitpid(-1, &status, WNOHANG) > 0)
53		;
54	errno = serrno;
55}
56
57int
58main(int argc, char *argv[])
59{
60	struct sigaction sa;
61	wordexp_t we;
62	int r;
63	int i;
64	char longdata[6 * 10000 + 1];
65
66	/* Test that the macros are there. */
67	(void)(WRDE_APPEND + WRDE_DOOFFS + WRDE_NOCMD + WRDE_REUSE +
68	    WRDE_SHOWERR + WRDE_UNDEF);
69	(void)(WRDE_BADCHAR + WRDE_BADVAL + WRDE_CMDSUB + WRDE_NOSPACE +
70	    WRDE_SYNTAX);
71
72	/* Simple test. */
73	r = wordexp("hello world", &we, 0);
74	assert(r == 0);
75	assert(we.we_wordc == 2);
76	assert(strcmp(we.we_wordv[0], "hello") == 0);
77	assert(strcmp(we.we_wordv[1], "world") == 0);
78	assert(we.we_wordv[2] == NULL);
79	wordfree(&we);
80
81	/* Long output. */
82	for (i = 0; i < 10000; i++)
83		snprintf(longdata + 6 * i, 7, "%05d ", i);
84	r = wordexp(longdata, &we, 0);
85	assert(r == 0);
86	assert(we.we_wordc == 10000);
87	assert(we.we_wordv[10000] == NULL);
88	wordfree(&we);
89
90	/* WRDE_DOOFFS */
91	we.we_offs = 3;
92	r = wordexp("hello world", &we, WRDE_DOOFFS);
93	assert(r == 0);
94	assert(we.we_wordc == 2);
95	assert(we.we_wordv[0] == NULL);
96	assert(we.we_wordv[1] == NULL);
97	assert(we.we_wordv[2] == NULL);
98	assert(strcmp(we.we_wordv[3], "hello") == 0);
99	assert(strcmp(we.we_wordv[4], "world") == 0);
100	assert(we.we_wordv[5] == NULL);
101	wordfree(&we);
102
103	/* WRDE_REUSE */
104	r = wordexp("hello world", &we, 0);
105	r = wordexp("hello world", &we, WRDE_REUSE);
106	assert(r == 0);
107	assert(we.we_wordc == 2);
108	assert(strcmp(we.we_wordv[0], "hello") == 0);
109	assert(strcmp(we.we_wordv[1], "world") == 0);
110	assert(we.we_wordv[2] == NULL);
111	wordfree(&we);
112
113	/* WRDE_APPEND */
114	r = wordexp("this is", &we, 0);
115	assert(r == 0);
116	r = wordexp("a test", &we, WRDE_APPEND);
117	assert(r == 0);
118	assert(we.we_wordc == 4);
119	assert(strcmp(we.we_wordv[0], "this") == 0);
120	assert(strcmp(we.we_wordv[1], "is") == 0);
121	assert(strcmp(we.we_wordv[2], "a") == 0);
122	assert(strcmp(we.we_wordv[3], "test") == 0);
123	assert(we.we_wordv[4] == NULL);
124	wordfree(&we);
125
126	/* WRDE_DOOFFS + WRDE_APPEND */
127	we.we_offs = 2;
128	r = wordexp("this is", &we, WRDE_DOOFFS);
129	assert(r == 0);
130	r = wordexp("a test", &we, WRDE_APPEND|WRDE_DOOFFS);
131	assert(r == 0);
132	r = wordexp("of wordexp", &we, WRDE_APPEND|WRDE_DOOFFS);
133	assert(r == 0);
134	assert(we.we_wordc == 6);
135	assert(we.we_wordv[0] == NULL);
136	assert(we.we_wordv[1] == NULL);
137	assert(strcmp(we.we_wordv[2], "this") == 0);
138	assert(strcmp(we.we_wordv[3], "is") == 0);
139	assert(strcmp(we.we_wordv[4], "a") == 0);
140	assert(strcmp(we.we_wordv[5], "test") == 0);
141	assert(strcmp(we.we_wordv[6], "of") == 0);
142	assert(strcmp(we.we_wordv[7], "wordexp") == 0);
143	assert(we.we_wordv[8] == NULL);
144	wordfree(&we);
145
146	/* WRDE_UNDEF */
147	r = wordexp("${dont_set_me}", &we, WRDE_UNDEF);
148	assert(r == WRDE_BADVAL);
149
150	/* WRDE_NOCMD */
151	r = wordexp("`date`", &we, WRDE_NOCMD);
152	assert(r == WRDE_CMDSUB);
153	r = wordexp("\"`date`\"", &we, WRDE_NOCMD);
154	assert(r == WRDE_CMDSUB);
155	r = wordexp("$(date)", &we, WRDE_NOCMD);
156	assert(r == WRDE_CMDSUB);
157	r = wordexp("\"$(date)\"", &we, WRDE_NOCMD);
158	assert(r == WRDE_CMDSUB);
159	r = wordexp("$((3+5))", &we, WRDE_NOCMD);
160	assert(r == 0);
161	r = wordexp("\\$\\(date\\)", &we, WRDE_NOCMD|WRDE_REUSE);
162	assert(r == 0);
163	r = wordexp("'`date`'", &we, WRDE_NOCMD|WRDE_REUSE);
164	assert(r == 0);
165	r = wordexp("'$(date)'", &we, WRDE_NOCMD|WRDE_REUSE);
166	assert(r == 0);
167	wordfree(&we);
168
169	/* WRDE_BADCHAR */
170	r = wordexp("'\n|&;<>(){}'", &we, 0);
171	assert(r == 0);
172	r = wordexp("\"\n|&;<>(){}\"", &we, WRDE_REUSE);
173	assert(r == 0);
174	r = wordexp("\\\n\\|\\&\\;\\<\\>\\(\\)\\{\\}", &we, WRDE_REUSE);
175	assert(r == 0);
176	wordfree(&we);
177	r = wordexp("test \n test", &we, 0);
178	assert(r == WRDE_BADCHAR);
179	r = wordexp("test | test", &we, 0);
180	assert(r == WRDE_BADCHAR);
181	r = wordexp("test & test", &we, 0);
182	assert(r == WRDE_BADCHAR);
183	r = wordexp("test ; test", &we, 0);
184	assert(r == WRDE_BADCHAR);
185	r = wordexp("test > test", &we, 0);
186	assert(r == WRDE_BADCHAR);
187	r = wordexp("test < test", &we, 0);
188	assert(r == WRDE_BADCHAR);
189	r = wordexp("test ( test", &we, 0);
190	assert(r == WRDE_BADCHAR);
191	r = wordexp("test ) test", &we, 0);
192	assert(r == WRDE_BADCHAR);
193	r = wordexp("test { test", &we, 0);
194	assert(r == WRDE_BADCHAR);
195	r = wordexp("test } test", &we, 0);
196	assert(r == WRDE_BADCHAR);
197
198	/* WRDE_SYNTAX */
199	r = wordexp("'", &we, 0);
200	assert(r == WRDE_SYNTAX);
201	r = wordexp("'", &we, WRDE_UNDEF);
202	assert(r == WRDE_SYNTAX);
203	r = wordexp("'\\'", &we, 0);
204	assert(r == 0);
205	assert(we.we_wordc == 1);
206	assert(strcmp(we.we_wordv[0], "\\") == 0);
207	assert(we.we_wordv[1] == NULL);
208	wordfree(&we);
209
210	/* With a SIGCHLD handler that reaps all zombies. */
211	sa.sa_flags = 0;
212	sigemptyset(&sa.sa_mask);
213	sa.sa_handler = chld_handler;
214	r = sigaction(SIGCHLD, &sa, NULL);
215	assert(r == 0);
216	r = wordexp("hello world", &we, 0);
217	assert(r == 0);
218	assert(we.we_wordc == 2);
219	assert(strcmp(we.we_wordv[0], "hello") == 0);
220	assert(strcmp(we.we_wordv[1], "world") == 0);
221	assert(we.we_wordv[2] == NULL);
222	wordfree(&we);
223	sa.sa_handler = SIG_DFL;
224	r = sigaction(SIGCHLD, &sa, NULL);
225	assert(r == 0);
226
227	/*
228	 * With IFS set to a non-default value (without depending on whether
229	 * IFS is inherited or not).
230	 */
231	r = setenv("IFS", ":", 1);
232	assert(r == 0);
233	r = wordexp("hello world", &we, 0);
234	assert(r == 0);
235	assert(we.we_wordc == 2);
236	assert(strcmp(we.we_wordv[0], "hello") == 0);
237	assert(strcmp(we.we_wordv[1], "world") == 0);
238	assert(we.we_wordv[2] == NULL);
239	wordfree(&we);
240	r = unsetenv("IFS");
241	assert(r == 0);
242
243	/*
244	 * With IFS set to a non-default value, and using it.
245	 */
246	r = setenv("IFS", ":", 1);
247	assert(r == 0);
248	r = wordexp("${IFS+hello:world}", &we, 0);
249	assert(r == 0);
250	assert(we.we_wordc == 2);
251	assert(strcmp(we.we_wordv[0], "hello") == 0);
252	assert(strcmp(we.we_wordv[1], "world") == 0);
253	assert(we.we_wordv[2] == NULL);
254	wordfree(&we);
255	r = unsetenv("IFS");
256	assert(r == 0);
257
258	printf("PASS wordexp()\n");
259	printf("PASS wordfree()\n");
260
261	return (0);
262}
263