test-wordexp.c revision 248987
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: head/tools/regression/lib/libc/gen/test-wordexp.c 248987 2013-04-01 20:50:07Z 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 /* With a SIGCHLD handler that reaps all zombies. */ 199 sa.sa_flags = 0; 200 sigemptyset(&sa.sa_mask); 201 sa.sa_handler = chld_handler; 202 r = sigaction(SIGCHLD, &sa, NULL); 203 assert(r == 0); 204 r = wordexp("hello world", &we, 0); 205 assert(r == 0); 206 assert(we.we_wordc == 2); 207 assert(strcmp(we.we_wordv[0], "hello") == 0); 208 assert(strcmp(we.we_wordv[1], "world") == 0); 209 assert(we.we_wordv[2] == NULL); 210 wordfree(&we); 211 sa.sa_handler = SIG_DFL; 212 r = sigaction(SIGCHLD, &sa, NULL); 213 assert(r == 0); 214 215 /* 216 * With IFS set to a non-default value (without depending on whether 217 * IFS is inherited or not). 218 */ 219 r = setenv("IFS", ":", 1); 220 assert(r == 0); 221 r = wordexp("hello world", &we, 0); 222 assert(r == 0); 223 assert(we.we_wordc == 2); 224 assert(strcmp(we.we_wordv[0], "hello") == 0); 225 assert(strcmp(we.we_wordv[1], "world") == 0); 226 assert(we.we_wordv[2] == NULL); 227 wordfree(&we); 228 r = unsetenv("IFS"); 229 assert(r == 0); 230 231 printf("PASS wordexp()\n"); 232 printf("PASS wordfree()\n"); 233 234 return (0); 235} 236