1 1.10 christos /* $NetBSD: getcwd.c,v 1.10 2011/08/18 02:32:32 christos Exp $ */ 2 1.1 sommerfe 3 1.1 sommerfe /*- 4 1.1 sommerfe * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 1.1 sommerfe * All rights reserved. 6 1.1 sommerfe * 7 1.1 sommerfe * This code is derived from software contributed to The NetBSD Foundation 8 1.1 sommerfe * by Bill Sommerfeld. 9 1.1 sommerfe * 10 1.1 sommerfe * Redistribution and use in source and binary forms, with or without 11 1.1 sommerfe * modification, are permitted provided that the following conditions 12 1.1 sommerfe * are met: 13 1.1 sommerfe * 1. Redistributions of source code must retain the above copyright 14 1.1 sommerfe * notice, this list of conditions and the following disclaimer. 15 1.1 sommerfe * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 sommerfe * notice, this list of conditions and the following disclaimer in the 17 1.1 sommerfe * documentation and/or other materials provided with the distribution. 18 1.1 sommerfe * 19 1.1 sommerfe * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 sommerfe * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 sommerfe * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 sommerfe * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 sommerfe * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 sommerfe * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 sommerfe * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 sommerfe * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 sommerfe * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 sommerfe * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 sommerfe * POSSIBILITY OF SUCH DAMAGE. 30 1.1 sommerfe */ 31 1.1 sommerfe 32 1.1 sommerfe /* 33 1.1 sommerfe * test SYS___getcwd. 34 1.1 sommerfe */ 35 1.1 sommerfe 36 1.1 sommerfe #include <assert.h> 37 1.2 sommerfe #include <err.h> 38 1.1 sommerfe #include <errno.h> 39 1.1 sommerfe #include <pwd.h> 40 1.1 sommerfe #include <stdio.h> 41 1.1 sommerfe #include <stdlib.h> 42 1.1 sommerfe #include <string.h> 43 1.1 sommerfe #include <time.h> 44 1.1 sommerfe #include <unistd.h> 45 1.1 sommerfe 46 1.1 sommerfe #include <sys/param.h> /* for MAXPATHLEN */ 47 1.1 sommerfe #include <sys/types.h> 48 1.1 sommerfe #include <sys/stat.h> 49 1.1 sommerfe #include <sys/wait.h> 50 1.1 sommerfe 51 1.1 sommerfe #include "getcwd.h" 52 1.1 sommerfe 53 1.8 perry int main(int, char *[]); 54 1.1 sommerfe 55 1.8 perry static void check1(char *dir, char *buf, char *calltext, 56 1.8 perry int actual, int expected, int experr); 57 1.1 sommerfe 58 1.8 perry static void time_old_getcwd(void); 59 1.8 perry static void time_kern_getcwd(void); 60 1.8 perry static void time_func(char *name, 61 1.8 perry void (*func)(void)); 62 1.8 perry 63 1.8 perry static void test_speed(void); 64 1.8 perry static void test___getcwd (void); 65 1.8 perry static void test___getcwd_perms (void); 66 1.8 perry static void test___getcwd_chroot(void); 67 1.1 sommerfe 68 1.8 perry static void stress_test_getcwd(void); 69 1.8 perry static void usage(char *progname); 70 1.3 sommerfe 71 1.3 sommerfe /* libc-private interface */ 72 1.8 perry int __getcwd(char *, size_t); 73 1.1 sommerfe 74 1.1 sommerfe /* 75 1.1 sommerfe * test cases: 76 1.1 sommerfe * NULL pointer 77 1.1 sommerfe * broken pointer 78 1.1 sommerfe * zero-length buffer 79 1.1 sommerfe * negative length 80 1.1 sommerfe * one-character buffer 81 1.1 sommerfe * two-character buffer 82 1.1 sommerfe * full-length buffer 83 1.1 sommerfe * large (uncacheable) name in path. 84 1.1 sommerfe * deleted directory 85 1.1 sommerfe * after rename of parent. 86 1.1 sommerfe * permission failure. 87 1.1 sommerfe * good pointer near end of address space 88 1.1 sommerfe * really huge length 89 1.1 sommerfe * really large (multi-block) directories 90 1.1 sommerfe * chroot interactions: 91 1.1 sommerfe * chroot, at / inside the directory. 92 1.1 sommerfe * chroot, at some other inside directory. 93 1.1 sommerfe */ 94 1.1 sommerfe 95 1.1 sommerfe /* 96 1.1 sommerfe * test cases not yet done: 97 1.1 sommerfe * -o union mount 98 1.1 sommerfe * chroot interactions: 99 1.1 sommerfe * chroot to mounted directory. 100 1.1 sommerfe * (i.e., proc a: chroot /foo; sleep; 101 1.1 sommerfe * proc b: mount blort /foo) 102 1.1 sommerfe * concurrent with force-unmounting of filesystem. 103 1.1 sommerfe */ 104 1.1 sommerfe 105 1.1 sommerfe #define bigname "Funkelhausersteinweitz.SIPBADMIN.a" /* don't ask */ 106 1.1 sommerfe #define littlename "getcwdtest" 107 1.1 sommerfe #define othername "testgetcwd" 108 1.1 sommerfe 109 1.1 sommerfe static int verbose = 0; 110 1.1 sommerfe static int test = 1; 111 1.1 sommerfe static int fail = 0; 112 1.1 sommerfe static int pass = 0; 113 1.1 sommerfe static int sleepflag = 0; 114 1.1 sommerfe 115 1.1 sommerfe static uid_t altid = -1; 116 1.1 sommerfe 117 1.1 sommerfe static void 118 1.1 sommerfe check1 (dir, buf, calltext, actual, expected, experr) 119 1.1 sommerfe char *dir; 120 1.1 sommerfe char *buf; 121 1.1 sommerfe char *calltext; 122 1.1 sommerfe int actual, expected, experr; 123 1.1 sommerfe { 124 1.1 sommerfe int ntest = test++; 125 1.1 sommerfe if (actual != expected) { 126 1.1 sommerfe fprintf(stderr, 127 1.1 sommerfe "test %d: in %s, %s failed; expected %d, got %d\n", 128 1.1 sommerfe ntest, dir, calltext, expected, actual); 129 1.1 sommerfe if (actual < 0) perror("getcwd"); 130 1.1 sommerfe fail++; 131 1.1 sommerfe } else if ((expected == -1) && (errno != (experr))) { 132 1.1 sommerfe fprintf(stderr, 133 1.1 sommerfe "test %d: in %s, %s failed; expected error %d, got %d\n", 134 1.1 sommerfe ntest, dir, calltext, experr, errno); 135 1.1 sommerfe if (actual < 0) perror("getcwd"); 136 1.1 sommerfe fail++; 137 1.1 sommerfe } else if ((expected > 0) && 138 1.1 sommerfe (buf != NULL) && 139 1.1 sommerfe (strcmp (dir, buf) != 0)) { 140 1.1 sommerfe fprintf(stderr, 141 1.1 sommerfe "test %d: in %s, %s got wrong dir %s\n", 142 1.1 sommerfe ntest, dir, calltext, buf); 143 1.1 sommerfe fail++; 144 1.1 sommerfe } else { 145 1.1 sommerfe if (expected > 0) { 146 1.1 sommerfe char newbuf[1024]; 147 1.1 sommerfe char *cp = old_getcwd(newbuf, sizeof(newbuf)); 148 1.1 sommerfe if (cp == NULL) { 149 1.1 sommerfe fail++; 150 1.1 sommerfe fprintf(stderr, 151 1.1 sommerfe "test %d: in %s, old getcwd failed!\n", 152 1.1 sommerfe ntest, dir); 153 1.1 sommerfe } else if (strcmp(cp, buf)) { 154 1.1 sommerfe fail++; 155 1.1 sommerfe fprintf(stderr, 156 1.1 sommerfe "test %d: in %s, old_getcwd returned different dir %s\n", 157 1.1 sommerfe ntest, dir, cp); 158 1.1 sommerfe } 159 1.1 sommerfe } 160 1.1 sommerfe pass++; 161 1.1 sommerfe if (verbose) 162 1.1 sommerfe printf("test %d: in %s, %s passed\n", ntest, dir, calltext); 163 1.1 sommerfe } 164 1.1 sommerfe if (sleepflag) 165 1.1 sommerfe sleep(1); 166 1.1 sommerfe } 167 1.1 sommerfe 168 1.1 sommerfe int nloops = 100; 169 1.1 sommerfe 170 1.1 sommerfe void 171 1.1 sommerfe time_old_getcwd() 172 1.1 sommerfe { 173 1.1 sommerfe char result_buf[1024]; 174 1.1 sommerfe if (old_getcwd(result_buf, 1024) == NULL) { 175 1.1 sommerfe fprintf(stderr, "old_getcwd failed during timing test!\n"); 176 1.1 sommerfe perror("old_getcwd"); 177 1.1 sommerfe exit(1); 178 1.1 sommerfe } 179 1.1 sommerfe 180 1.1 sommerfe } 181 1.1 sommerfe 182 1.1 sommerfe void 183 1.1 sommerfe time_kern_getcwd() 184 1.1 sommerfe { 185 1.1 sommerfe char result_buf[1024]; 186 1.1 sommerfe if (__getcwd(result_buf, sizeof(result_buf)) < 0) { 187 1.1 sommerfe fprintf(stderr, "getcwd failed during timing test!"); 188 1.1 sommerfe perror("getcwd"); 189 1.1 sommerfe exit(1); 190 1.1 sommerfe } 191 1.1 sommerfe } 192 1.1 sommerfe 193 1.1 sommerfe static void 194 1.1 sommerfe time_func(name, func) 195 1.1 sommerfe char *name; 196 1.8 perry void (*func)(void); 197 1.1 sommerfe { 198 1.1 sommerfe struct timeval before, after; 199 1.1 sommerfe double delta_t; 200 1.1 sommerfe 201 1.1 sommerfe int i; 202 1.1 sommerfe chdir ("/usr/share/examples/emul/ultrix/etc"); 203 1.1 sommerfe 204 1.1 sommerfe gettimeofday(&before, 0); 205 1.1 sommerfe for (i=0; i<nloops; i++) { 206 1.1 sommerfe (*func)(); 207 1.1 sommerfe } 208 1.1 sommerfe gettimeofday(&after, 0); 209 1.1 sommerfe 210 1.1 sommerfe delta_t = after.tv_sec - before.tv_sec; 211 1.1 sommerfe 212 1.1 sommerfe delta_t += ((double)(after.tv_usec - before.tv_usec))/1000000.0; 213 1.1 sommerfe 214 1.1 sommerfe printf("%s: %d calls in %10.3f seconds; ", name, nloops, delta_t); 215 1.1 sommerfe printf("%10.6f ms/call\n", (delta_t*1000.0)/nloops); 216 1.1 sommerfe } 217 1.1 sommerfe 218 1.1 sommerfe void 219 1.1 sommerfe test_speed() 220 1.1 sommerfe { 221 1.1 sommerfe int i; 222 1.1 sommerfe for (i=0; i<5; i++) 223 1.1 sommerfe time_func("kernel getcwd", time_kern_getcwd); 224 1.1 sommerfe 225 1.1 sommerfe for (i=0; i<5; i++) 226 1.1 sommerfe time_func("old user-space getcwd", time_old_getcwd); 227 1.1 sommerfe } 228 1.1 sommerfe 229 1.1 sommerfe #define CHECK(dir, call, ret, err) \ 230 1.1 sommerfe check1((dir), kbuf, #call, (call), (ret), (err)) 231 1.1 sommerfe 232 1.1 sommerfe 233 1.1 sommerfe void 234 1.1 sommerfe test___getcwd_perms() 235 1.1 sommerfe { 236 1.1 sommerfe char kbuf[1024]; 237 1.1 sommerfe 238 1.2 sommerfe if (geteuid() != 0) 239 1.2 sommerfe { 240 1.2 sommerfe fprintf(stderr, "Not root; skipping permission tests\n"); 241 1.2 sommerfe return; 242 1.2 sommerfe } 243 1.2 sommerfe 244 1.1 sommerfe mkdir ("/tmp/permdir", 0700); 245 1.1 sommerfe mkdir ("/tmp/permdir/subdir", 0755); 246 1.1 sommerfe chdir ("/tmp/permdir/subdir"); 247 1.1 sommerfe 248 1.1 sommerfe seteuid(altid); 249 1.1 sommerfe 250 1.1 sommerfe CHECK("/tmp/permdir/subdir", __getcwd(kbuf, sizeof(kbuf)), -1, EACCES); 251 1.5 sommerfe 252 1.5 sommerfe seteuid(0); 253 1.5 sommerfe chdir ("/"); 254 1.5 sommerfe rmdir ("/tmp/permdir/subdir"); 255 1.5 sommerfe rmdir ("/tmp/permdir"); 256 1.5 sommerfe 257 1.5 sommerfe mkdir ("/tmp/permdir", 0755); 258 1.5 sommerfe mkdir ("/tmp/permdir/subdir", 0711); 259 1.5 sommerfe chdir ("/tmp/permdir/subdir"); 260 1.5 sommerfe 261 1.5 sommerfe seteuid(altid); 262 1.5 sommerfe 263 1.5 sommerfe CHECK("/tmp/permdir/subdir", __getcwd(kbuf, sizeof(kbuf)), 20, 0); 264 1.1 sommerfe 265 1.1 sommerfe seteuid(0); 266 1.1 sommerfe chdir ("/"); 267 1.1 sommerfe rmdir ("/tmp/permdir/subdir"); 268 1.1 sommerfe rmdir ("/tmp/permdir"); 269 1.1 sommerfe } 270 1.1 sommerfe 271 1.1 sommerfe void 272 1.1 sommerfe test___getcwd_chroot() 273 1.1 sommerfe { 274 1.1 sommerfe int pid, status; 275 1.1 sommerfe char kbuf[1024]; 276 1.1 sommerfe 277 1.2 sommerfe if (geteuid() != 0) 278 1.2 sommerfe { 279 1.2 sommerfe fprintf(stderr, "Not root; skipping chroot tests\n"); 280 1.2 sommerfe return; 281 1.2 sommerfe } 282 1.2 sommerfe 283 1.1 sommerfe /* XXX we need fchroot to do this properly.. */ 284 1.1 sommerfe mkdir ("/tmp/chrootdir", 0755); 285 1.1 sommerfe mkdir ("/tmp/chrootdir/subdir", 0755); 286 1.1 sommerfe 287 1.1 sommerfe chdir ("/tmp/chrootdir"); 288 1.1 sommerfe 289 1.1 sommerfe CHECK ("/tmp/chrootdir", __getcwd(kbuf, sizeof(kbuf)), 15, 0); 290 1.1 sommerfe 291 1.1 sommerfe fflush(NULL); 292 1.1 sommerfe 293 1.1 sommerfe pid = fork(); 294 1.1 sommerfe 295 1.1 sommerfe if (pid < 0) { 296 1.1 sommerfe perror("fork"); 297 1.1 sommerfe fail++; 298 1.1 sommerfe } else if (pid == 0) { 299 1.1 sommerfe fail = 0; 300 1.1 sommerfe pass = 0; 301 1.1 sommerfe /* chroot to root of filesystem (assuming MFS /tmp) */ 302 1.1 sommerfe chroot ("/tmp"); 303 1.1 sommerfe CHECK ("/chrootdir", __getcwd(kbuf, sizeof(kbuf)), 11, 0); 304 1.1 sommerfe /* chroot to further down */ 305 1.1 sommerfe chroot ("/chrootdir"); 306 1.1 sommerfe CHECK ("/", __getcwd(kbuf, sizeof(kbuf)), 2, 0); 307 1.1 sommerfe chdir("subdir"); 308 1.1 sommerfe CHECK ("/subdir", __getcwd(kbuf, sizeof(kbuf)), 8, 0); 309 1.1 sommerfe 310 1.1 sommerfe if (fail) 311 1.1 sommerfe exit(1); 312 1.1 sommerfe else 313 1.1 sommerfe exit(0); 314 1.1 sommerfe } else { 315 1.1 sommerfe waitpid(pid, &status, 0); 316 1.1 sommerfe 317 1.1 sommerfe if (WIFEXITED(status) && 318 1.1 sommerfe (WEXITSTATUS(status) == 0)) 319 1.1 sommerfe pass++; 320 1.1 sommerfe else 321 1.1 sommerfe fail++; 322 1.1 sommerfe 323 1.1 sommerfe } 324 1.1 sommerfe 325 1.1 sommerfe chdir ("/"); 326 1.1 sommerfe rmdir ("/tmp/chrootdir/subdir"); 327 1.1 sommerfe rmdir ("/tmp/chrootdir"); 328 1.1 sommerfe } 329 1.1 sommerfe 330 1.1 sommerfe 331 1.1 sommerfe 332 1.1 sommerfe 333 1.1 sommerfe void 334 1.1 sommerfe test___getcwd() 335 1.1 sommerfe { 336 1.1 sommerfe int i; 337 1.1 sommerfe static char kbuf[1024]; 338 1.1 sommerfe 339 1.1 sommerfe chdir("/"); 340 1.1 sommerfe 341 1.1 sommerfe CHECK("/", __getcwd(0, 0), -1, ERANGE); 342 1.1 sommerfe CHECK("/", __getcwd(0, -1), -1, ERANGE); 343 1.1 sommerfe CHECK("/", __getcwd(kbuf, 0xdeadbeef), -1, ERANGE); /* large negative */ 344 1.4 sommerfe CHECK("/", __getcwd(kbuf, 0x7000beef), 2, 0); /* large positive, rounds down */ 345 1.4 sommerfe CHECK("/", __getcwd(kbuf, 0x10000), 2, 0); /* slightly less large positive, rounds down */ 346 1.10 christos CHECK("/", __getcwd((void *)0x10000, sizeof(kbuf)), -1, EFAULT); /* outside address space */ 347 1.1 sommerfe CHECK("/", __getcwd(0, 30), -1, EFAULT); 348 1.1 sommerfe CHECK("/", __getcwd((void*)0xdeadbeef, 30), -1, EFAULT); 349 1.1 sommerfe CHECK("/", __getcwd(kbuf, 2), 2, 0); 350 1.1 sommerfe assert (strcmp(kbuf, "/") == 0); 351 1.1 sommerfe CHECK("/", __getcwd(kbuf, sizeof(kbuf)), 2, 0); 352 1.1 sommerfe 353 1.1 sommerfe CHECK("/", __getcwd(kbuf, 0), -1, ERANGE); 354 1.1 sommerfe CHECK("/", __getcwd(kbuf, 1), -1, ERANGE); 355 1.1 sommerfe 356 1.1 sommerfe chdir("/sbin"); 357 1.1 sommerfe CHECK("/sbin", __getcwd(kbuf, sizeof(kbuf)), 6, 0); 358 1.1 sommerfe /* verify that cacheable path gets range check right.. */ 359 1.1 sommerfe CHECK("/sbin", __getcwd(kbuf, 3), -1, ERANGE); 360 1.1 sommerfe chdir("/etc/mtree"); 361 1.1 sommerfe CHECK("/etc/mtree", __getcwd(kbuf, sizeof(kbuf)), 11, 0); 362 1.1 sommerfe CHECK("/etc/mtree", __getcwd(kbuf, sizeof(kbuf)), 11, 0); 363 1.1 sommerfe /* mount point */ 364 1.1 sommerfe chdir("/usr/bin"); 365 1.1 sommerfe CHECK("/usr/bin", __getcwd(kbuf, sizeof(kbuf)), 9, 0); 366 1.1 sommerfe 367 1.1 sommerfe /* really large (non-cacheable) entry name */ 368 1.1 sommerfe chdir("/tmp"); 369 1.1 sommerfe (void) rmdir(bigname); 370 1.1 sommerfe mkdir(bigname, 0755); 371 1.1 sommerfe chdir(bigname); 372 1.1 sommerfe 373 1.1 sommerfe /* verify that non-cachable path gets range check right.. */ 374 1.1 sommerfe CHECK("/tmp/" bigname, __getcwd(kbuf, 10), -1, ERANGE); 375 1.1 sommerfe CHECK("/tmp/" bigname, __getcwd(kbuf, sizeof(kbuf)), 40, 0); 376 1.1 sommerfe 377 1.1 sommerfe if (rmdir("/tmp/" bigname) < 0) { 378 1.1 sommerfe perror("rmdir"); 379 1.1 sommerfe } 380 1.1 sommerfe CHECK("deleted directory", __getcwd(kbuf, sizeof(kbuf)), -1, ENOENT); 381 1.1 sommerfe 382 1.1 sommerfe chdir("/tmp"); 383 1.1 sommerfe (void) rmdir(littlename); 384 1.1 sommerfe mkdir(littlename, 0755); 385 1.1 sommerfe chdir(littlename); 386 1.1 sommerfe CHECK("/tmp/" littlename, __getcwd(kbuf, sizeof(kbuf)), 16, 0); 387 1.1 sommerfe if (rename("/tmp/" littlename, "/tmp/" othername) < 0) { 388 1.1 sommerfe perror("rename"); 389 1.1 sommerfe fail++; 390 1.1 sommerfe } 391 1.1 sommerfe CHECK("/tmp/" othername, __getcwd(kbuf, sizeof(kbuf)), 16, 0); 392 1.1 sommerfe if (rmdir("/tmp/" othername) < 0) { 393 1.1 sommerfe perror("rmdir"); 394 1.1 sommerfe fail++; 395 1.1 sommerfe } 396 1.1 sommerfe CHECK("deleted directory", __getcwd(kbuf, sizeof(kbuf)), -1, ENOENT); 397 1.1 sommerfe 398 1.1 sommerfe mkdir("/tmp/bigdir", 0755); 399 1.1 sommerfe for (i=0; i<nloops; i++) { 400 1.1 sommerfe char buf[MAXPATHLEN]; 401 1.1 sommerfe snprintf(buf, MAXPATHLEN, "/tmp/bigdir/bigsubdirwithanamewhichistoolongtocache%04d", i); 402 1.1 sommerfe (void)rmdir(buf); 403 1.1 sommerfe if (mkdir (buf, 0755) < 0) { 404 1.1 sommerfe perror("mkdir"); 405 1.1 sommerfe fail++; 406 1.1 sommerfe break; 407 1.1 sommerfe } 408 1.1 sommerfe } 409 1.1 sommerfe for (i=0; i<nloops; i++) { 410 1.1 sommerfe char buf[MAXPATHLEN]; 411 1.1 sommerfe snprintf(buf, MAXPATHLEN, "/tmp/bigdir/bigsubdirwithanamewhichistoolongtocache%04d", i); 412 1.1 sommerfe if (chdir(buf) < 0) { 413 1.1 sommerfe perror("chdir"); 414 1.1 sommerfe fail++; 415 1.1 sommerfe break; 416 1.1 sommerfe } 417 1.1 sommerfe CHECK(buf, __getcwd(kbuf, sizeof(kbuf)), strlen(buf)+1, 0); 418 1.1 sommerfe } 419 1.1 sommerfe for (i=0; i<nloops; i++) { 420 1.1 sommerfe char buf[MAXPATHLEN]; 421 1.1 sommerfe snprintf(buf, MAXPATHLEN, "/tmp/bigdir/bigsubdirwithanamewhichistoolongtocache%04d", i); 422 1.1 sommerfe (void)rmdir(buf); 423 1.1 sommerfe } 424 1.1 sommerfe (void)rmdir("/tmp/bigdir"); 425 1.1 sommerfe 426 1.1 sommerfe test___getcwd_perms(); 427 1.1 sommerfe test___getcwd_chroot(); 428 1.1 sommerfe } 429 1.1 sommerfe 430 1.1 sommerfe 431 1.1 sommerfe void 432 1.1 sommerfe stress_test_getcwd() 433 1.1 sommerfe { 434 1.1 sommerfe char buf[MAXPATHLEN]; 435 1.1 sommerfe char ubuf[MAXPATHLEN]; 436 1.1 sommerfe char kbuf[MAXPATHLEN]; 437 1.1 sommerfe printf("reading directories from stdin..\n"); 438 1.1 sommerfe while (fgets(buf, MAXPATHLEN, stdin)) { 439 1.1 sommerfe char *cp = strrchr(buf, '\n'); 440 1.1 sommerfe if (cp) *cp = '\0'; 441 1.1 sommerfe 442 1.2 sommerfe if (chdir (buf) < 0) { 443 1.2 sommerfe warn("Can't change directory to %s", buf); 444 1.2 sommerfe continue; 445 1.2 sommerfe } 446 1.2 sommerfe 447 1.1 sommerfe 448 1.1 sommerfe cp = old_getcwd (ubuf, MAXPATHLEN); 449 1.2 sommerfe if (strcmp(buf, ubuf) != 0) { 450 1.7 grant warnx("In %s, old_getcwd says %s", 451 1.2 sommerfe buf, ubuf); 452 1.2 sommerfe } 453 1.2 sommerfe 454 1.1 sommerfe 455 1.1 sommerfe CHECK(buf, __getcwd (kbuf, MAXPATHLEN), 456 1.1 sommerfe strlen(ubuf)+1, 0); 457 1.1 sommerfe } 458 1.1 sommerfe } 459 1.1 sommerfe 460 1.1 sommerfe 461 1.1 sommerfe /* 462 1.1 sommerfe * - large directories. 463 1.1 sommerfe * 464 1.1 sommerfe * - every single filesystem type 465 1.1 sommerfe * 466 1.1 sommerfe * - walk filesystem, compare sys_getcwd with getcwd for each 467 1.1 sommerfe * directory 468 1.1 sommerfe */ 469 1.1 sommerfe 470 1.1 sommerfe void 471 1.1 sommerfe usage(progname) 472 1.1 sommerfe char *progname; 473 1.1 sommerfe { 474 1.1 sommerfe fprintf(stderr, "usage: %s [-srpvw] [-l nloops]\n", progname); 475 1.1 sommerfe exit(1); 476 1.1 sommerfe } 477 1.1 sommerfe 478 1.1 sommerfe int run_stress = 0; 479 1.1 sommerfe int run_regression = 0; 480 1.1 sommerfe int run_performance = 0; 481 1.1 sommerfe 482 1.1 sommerfe int 483 1.1 sommerfe main(argc, argv) 484 1.1 sommerfe int argc; 485 1.1 sommerfe char **argv; 486 1.1 sommerfe { 487 1.1 sommerfe int ch; 488 1.1 sommerfe char *progname = argv[0]; 489 1.1 sommerfe 490 1.1 sommerfe uid_from_user("nobody", &altid); 491 1.1 sommerfe 492 1.1 sommerfe while ((ch = getopt(argc, argv, "srpvwl:u:")) != -1) 493 1.1 sommerfe switch (ch) { 494 1.1 sommerfe case 's': 495 1.1 sommerfe run_stress++; 496 1.1 sommerfe break; 497 1.1 sommerfe case 'r': 498 1.1 sommerfe run_regression++; 499 1.1 sommerfe break; 500 1.1 sommerfe case 'p': 501 1.1 sommerfe run_performance++; 502 1.1 sommerfe break; 503 1.1 sommerfe case 'v': 504 1.1 sommerfe verbose++; 505 1.1 sommerfe break; 506 1.1 sommerfe case 'w': 507 1.1 sommerfe sleepflag++; 508 1.1 sommerfe break; 509 1.1 sommerfe case 'l': 510 1.1 sommerfe nloops = atoi(optarg); 511 1.1 sommerfe if (nloops == 0) 512 1.1 sommerfe nloops = 100; 513 1.1 sommerfe break; 514 1.1 sommerfe case 'u': 515 1.1 sommerfe if (uid_from_user(optarg, &altid) != 0) { 516 1.1 sommerfe fprintf(stderr, "unknown user %s\n", optarg); 517 1.1 sommerfe usage(progname); 518 1.1 sommerfe exit(1); 519 1.1 sommerfe } 520 1.1 sommerfe break; 521 1.1 sommerfe case '?': 522 1.1 sommerfe default: 523 1.1 sommerfe usage(progname); 524 1.1 sommerfe } 525 1.1 sommerfe if (argc != optind) 526 1.1 sommerfe usage(progname); 527 1.1 sommerfe 528 1.1 sommerfe if (run_regression) 529 1.1 sommerfe test___getcwd(); 530 1.1 sommerfe 531 1.1 sommerfe if (!fail && run_performance) 532 1.1 sommerfe test_speed(); 533 1.1 sommerfe 534 1.1 sommerfe if (!fail && run_stress) 535 1.1 sommerfe stress_test_getcwd(); 536 1.1 sommerfe 537 1.1 sommerfe 538 1.1 sommerfe if (verbose) 539 1.1 sommerfe printf ("%d passes\n", pass); 540 1.1 sommerfe if (!fail) 541 1.1 sommerfe exit (0); 542 1.1 sommerfe else { 543 1.1 sommerfe printf("%d failures\n", fail); 544 1.1 sommerfe exit(1); 545 1.1 sommerfe } 546 1.1 sommerfe } 547 1.1 sommerfe 548 1.1 sommerfe 549