]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - lib/libc/tests/gen/wordexp_test.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / lib / libc / tests / gen / wordexp_test.c
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$");
34
35 #include <sys/wait.h>
36 #include <errno.h>
37 #include <signal.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <wordexp.h>
42
43 #include <atf-c.h>
44
45 static void
46 chld_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
57 ATF_TC_WITHOUT_HEAD(simple_test);
58 ATF_TC_BODY(simple_test, tc)
59 {
60         wordexp_t we;
61         int r;
62
63         /* Test that the macros are there. */
64         (void)(WRDE_APPEND + WRDE_DOOFFS + WRDE_NOCMD + WRDE_REUSE +
65             WRDE_SHOWERR + WRDE_UNDEF);
66         (void)(WRDE_BADCHAR + WRDE_BADVAL + WRDE_CMDSUB + WRDE_NOSPACE +
67             WRDE_SYNTAX);
68
69         /* Simple test. */
70         r = wordexp("hello world", &we, 0);
71         ATF_REQUIRE(r == 0);
72         ATF_REQUIRE(we.we_wordc == 2);
73         ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0);
74         ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0);
75         ATF_REQUIRE(we.we_wordv[2] == NULL);
76         wordfree(&we);
77 }
78
79 ATF_TC_WITHOUT_HEAD(long_output_test);
80 ATF_TC_BODY(long_output_test, tc)
81 {
82         char longdata[6 * 10000 + 1];
83         wordexp_t we;
84         int i, r;
85
86         /* Long output. */
87         for (i = 0; i < 10000; i++)
88                 snprintf(longdata + 6 * i, 7, "%05d ", i);
89         r = wordexp(longdata, &we, 0);
90         ATF_REQUIRE(r == 0);
91         ATF_REQUIRE(we.we_wordc == 10000);
92         ATF_REQUIRE(we.we_wordv[10000] == NULL);
93         wordfree(&we);
94 }
95
96 ATF_TC_WITHOUT_HEAD(WRDE_DOOFFS_test);
97 ATF_TC_BODY(WRDE_DOOFFS_test, tc)
98 {
99         wordexp_t we;
100         int r;
101
102         we.we_offs = 3;
103         r = wordexp("hello world", &we, WRDE_DOOFFS);
104         ATF_REQUIRE(r == 0);
105         ATF_REQUIRE(we.we_wordc == 2);
106         ATF_REQUIRE(we.we_wordv[0] == NULL);
107         ATF_REQUIRE(we.we_wordv[1] == NULL);
108         ATF_REQUIRE(we.we_wordv[2] == NULL);
109         ATF_REQUIRE(strcmp(we.we_wordv[3], "hello") == 0);
110         ATF_REQUIRE(strcmp(we.we_wordv[4], "world") == 0);
111         ATF_REQUIRE(we.we_wordv[5] == NULL);
112         wordfree(&we);
113 }
114
115 ATF_TC_WITHOUT_HEAD(WRDE_REUSE_test);
116 ATF_TC_BODY(WRDE_REUSE_test, tc)
117 {
118         wordexp_t we;
119         int r;
120
121         r = wordexp("hello world", &we, 0);
122         r = wordexp("hello world", &we, WRDE_REUSE);
123         ATF_REQUIRE(r == 0);
124         ATF_REQUIRE(we.we_wordc == 2);
125         ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0);
126         ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0);
127         ATF_REQUIRE(we.we_wordv[2] == NULL);
128         wordfree(&we);
129 }
130
131 ATF_TC_WITHOUT_HEAD(WRDE_APPEND_test);
132 ATF_TC_BODY(WRDE_APPEND_test, tc)
133 {
134         wordexp_t we;
135         int r;
136
137         r = wordexp("this is", &we, 0);
138         ATF_REQUIRE(r == 0);
139         r = wordexp("a test", &we, WRDE_APPEND);
140         ATF_REQUIRE(r == 0);
141         ATF_REQUIRE(we.we_wordc == 4);
142         ATF_REQUIRE(strcmp(we.we_wordv[0], "this") == 0);
143         ATF_REQUIRE(strcmp(we.we_wordv[1], "is") == 0);
144         ATF_REQUIRE(strcmp(we.we_wordv[2], "a") == 0);
145         ATF_REQUIRE(strcmp(we.we_wordv[3], "test") == 0);
146         ATF_REQUIRE(we.we_wordv[4] == NULL);
147         wordfree(&we);
148 }
149
150 ATF_TC_WITHOUT_HEAD(WRDE_DOOFFS__WRDE_APPEND_test);
151 ATF_TC_BODY(WRDE_DOOFFS__WRDE_APPEND_test, tc)
152 {
153         wordexp_t we;
154         int r;
155
156         we.we_offs = 2;
157         r = wordexp("this is", &we, WRDE_DOOFFS);
158         ATF_REQUIRE(r == 0);
159         r = wordexp("a test", &we, WRDE_APPEND|WRDE_DOOFFS);
160         ATF_REQUIRE(r == 0);
161         r = wordexp("of wordexp", &we, WRDE_APPEND|WRDE_DOOFFS);
162         ATF_REQUIRE(r == 0);
163         ATF_REQUIRE(we.we_wordc == 6);
164         ATF_REQUIRE(we.we_wordv[0] == NULL);
165         ATF_REQUIRE(we.we_wordv[1] == NULL);
166         ATF_REQUIRE(strcmp(we.we_wordv[2], "this") == 0);
167         ATF_REQUIRE(strcmp(we.we_wordv[3], "is") == 0);
168         ATF_REQUIRE(strcmp(we.we_wordv[4], "a") == 0);
169         ATF_REQUIRE(strcmp(we.we_wordv[5], "test") == 0);
170         ATF_REQUIRE(strcmp(we.we_wordv[6], "of") == 0);
171         ATF_REQUIRE(strcmp(we.we_wordv[7], "wordexp") == 0);
172         ATF_REQUIRE(we.we_wordv[8] == NULL);
173         wordfree(&we);
174 }
175
176 ATF_TC_WITHOUT_HEAD(WRDE_UNDEF_test);
177 ATF_TC_BODY(WRDE_UNDEF_test, tc)
178 {
179         wordexp_t we;
180         int r;
181
182         r = wordexp("${dont_set_me}", &we, WRDE_UNDEF);
183         ATF_REQUIRE(r == WRDE_BADVAL);
184 }
185
186 ATF_TC_WITHOUT_HEAD(WRDE_NOCMD_test);
187 ATF_TC_BODY(WRDE_NOCMD_test, tc)
188 {
189         wordexp_t we;
190         int r;
191
192         r = wordexp("`date`", &we, WRDE_NOCMD);
193         ATF_REQUIRE(r == WRDE_CMDSUB);
194         r = wordexp("\"`date`\"", &we, WRDE_NOCMD);
195         ATF_REQUIRE(r == WRDE_CMDSUB);
196         r = wordexp("$(date)", &we, WRDE_NOCMD);
197         ATF_REQUIRE(r == WRDE_CMDSUB);
198         r = wordexp("\"$(date)\"", &we, WRDE_NOCMD);
199         ATF_REQUIRE(r == WRDE_CMDSUB);
200         r = wordexp("$((3+5))", &we, WRDE_NOCMD);
201         ATF_REQUIRE(r == 0);
202         r = wordexp("\\$\\(date\\)", &we, WRDE_NOCMD|WRDE_REUSE);
203         ATF_REQUIRE(r == 0);
204         r = wordexp("'`date`'", &we, WRDE_NOCMD|WRDE_REUSE);
205         ATF_REQUIRE(r == 0);
206         r = wordexp("'$(date)'", &we, WRDE_NOCMD|WRDE_REUSE);
207         ATF_REQUIRE(r == 0);
208         wordfree(&we);
209 }
210
211 ATF_TC_WITHOUT_HEAD(WRDE_BADCHAR_test);
212 ATF_TC_BODY(WRDE_BADCHAR_test, tc)
213 {
214         wordexp_t we;
215         int r;
216
217         r = wordexp("'\n|&;<>(){}'", &we, 0);
218         ATF_REQUIRE(r == 0);
219         r = wordexp("\"\n|&;<>(){}\"", &we, WRDE_REUSE);
220         ATF_REQUIRE(r == 0);
221         r = wordexp("\\\n\\|\\&\\;\\<\\>\\(\\)\\{\\}", &we, WRDE_REUSE);
222         ATF_REQUIRE(r == 0);
223         wordfree(&we);
224         r = wordexp("test \n test", &we, 0);
225         ATF_REQUIRE(r == WRDE_BADCHAR);
226         r = wordexp("test | test", &we, 0);
227         ATF_REQUIRE(r == WRDE_BADCHAR);
228         r = wordexp("test & test", &we, 0);
229         ATF_REQUIRE(r == WRDE_BADCHAR);
230         r = wordexp("test ; test", &we, 0);
231         ATF_REQUIRE(r == WRDE_BADCHAR);
232         r = wordexp("test > test", &we, 0);
233         ATF_REQUIRE(r == WRDE_BADCHAR);
234         r = wordexp("test < test", &we, 0);
235         ATF_REQUIRE(r == WRDE_BADCHAR);
236         r = wordexp("test ( test", &we, 0);
237         ATF_REQUIRE(r == WRDE_BADCHAR);
238         r = wordexp("test ) test", &we, 0);
239         ATF_REQUIRE(r == WRDE_BADCHAR);
240         r = wordexp("test { test", &we, 0);
241         ATF_REQUIRE(r == WRDE_BADCHAR);
242         r = wordexp("test } test", &we, 0);
243         ATF_REQUIRE(r == WRDE_BADCHAR);
244 }
245
246 ATF_TC_WITHOUT_HEAD(WRDE_SYNTAX_test);
247 ATF_TC_BODY(WRDE_SYNTAX_test, tc)
248 {
249         wordexp_t we;
250         int r;
251
252         r = wordexp("'", &we, 0);
253         ATF_REQUIRE(r == WRDE_SYNTAX);
254         r = wordexp("'", &we, WRDE_UNDEF);
255         ATF_REQUIRE(r == WRDE_SYNTAX);
256         r = wordexp("'\\'", &we, 0);
257         ATF_REQUIRE(r == 0);
258         ATF_REQUIRE(we.we_wordc == 1);
259         ATF_REQUIRE(strcmp(we.we_wordv[0], "\\") == 0);
260         ATF_REQUIRE(we.we_wordv[1] == NULL);
261         wordfree(&we);
262         /* Two syntax errors that are not detected by the current we_check(). */
263         r = wordexp("${IFS:+'}", &we, 0);
264         ATF_REQUIRE(r == WRDE_SYNTAX);
265         r = wordexp("${IFS:+'}", &we, WRDE_UNDEF);
266         ATF_REQUIRE(r == WRDE_SYNTAX);
267         r = wordexp("$(case)", &we, 0);
268         ATF_REQUIRE(r == WRDE_SYNTAX);
269         r = wordexp("$(case)", &we, WRDE_UNDEF);
270         ATF_REQUIRE(r == WRDE_SYNTAX);
271 }
272
273 ATF_TC_WITHOUT_HEAD(with_SIGCHILD_handler_test);
274 ATF_TC_BODY(with_SIGCHILD_handler_test, tc)
275 {
276         struct sigaction sa;
277         wordexp_t we;
278         int r;
279
280         /* With a SIGCHLD handler that reaps all zombies. */
281         sa.sa_flags = 0;
282         sigemptyset(&sa.sa_mask);
283         sa.sa_handler = chld_handler;
284         r = sigaction(SIGCHLD, &sa, NULL);
285         ATF_REQUIRE(r == 0);
286         r = wordexp("hello world", &we, 0);
287         ATF_REQUIRE(r == 0);
288         ATF_REQUIRE(we.we_wordc == 2);
289         ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0);
290         ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0);
291         ATF_REQUIRE(we.we_wordv[2] == NULL);
292         wordfree(&we);
293         sa.sa_handler = SIG_DFL;
294         r = sigaction(SIGCHLD, &sa, NULL);
295         ATF_REQUIRE(r == 0);
296 }
297
298 ATF_TC_WITHOUT_HEAD(with_unused_non_default_IFS_test);
299 ATF_TC_BODY(with_unused_non_default_IFS_test, tc)
300 {
301         wordexp_t we;
302         int r;
303
304         /*
305          * With IFS set to a non-default value (without depending on whether
306          * IFS is inherited or not).
307          */
308         r = setenv("IFS", ":", 1);
309         ATF_REQUIRE(r == 0);
310         r = wordexp("hello world", &we, 0);
311         ATF_REQUIRE(r == 0);
312         ATF_REQUIRE(we.we_wordc == 2);
313         ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0);
314         ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0);
315         ATF_REQUIRE(we.we_wordv[2] == NULL);
316         wordfree(&we);
317         r = unsetenv("IFS");
318         ATF_REQUIRE(r == 0);
319 }
320
321 ATF_TC_WITHOUT_HEAD(with_used_non_default_IFS_test);
322 ATF_TC_BODY(with_used_non_default_IFS_test, tc)
323 {
324         wordexp_t we;
325         int r;
326
327         /*
328          * With IFS set to a non-default value, and using it.
329          */
330         r = setenv("IFS", ":", 1);
331         ATF_REQUIRE(r == 0);
332         r = wordexp("${IFS+hello:world}", &we, 0);
333         ATF_REQUIRE(r == 0);
334         ATF_REQUIRE(we.we_wordc == 2);
335         ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0);
336         ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0);
337         ATF_REQUIRE(we.we_wordv[2] == NULL);
338         wordfree(&we);
339         r = unsetenv("IFS");
340         ATF_REQUIRE(r == 0);
341 }
342
343 ATF_TP_ADD_TCS(tp)
344 {
345         ATF_TP_ADD_TC(tp, simple_test);
346         ATF_TP_ADD_TC(tp, long_output_test);
347         ATF_TP_ADD_TC(tp, WRDE_DOOFFS_test);
348         ATF_TP_ADD_TC(tp, WRDE_REUSE_test);
349         ATF_TP_ADD_TC(tp, WRDE_APPEND_test);
350         ATF_TP_ADD_TC(tp, WRDE_DOOFFS__WRDE_APPEND_test);
351         ATF_TP_ADD_TC(tp, WRDE_UNDEF_test);
352         ATF_TP_ADD_TC(tp, WRDE_NOCMD_test);
353         ATF_TP_ADD_TC(tp, WRDE_BADCHAR_test);
354         ATF_TP_ADD_TC(tp, WRDE_SYNTAX_test);
355         ATF_TP_ADD_TC(tp, with_SIGCHILD_handler_test);
356         ATF_TP_ADD_TC(tp, with_unused_non_default_IFS_test);
357         ATF_TP_ADD_TC(tp, with_used_non_default_IFS_test);
358
359         return (atf_no_error());
360 }