/* $NetBSD: getcwd.c,v 1.10 2011/08/18 02:32:32 christos Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Bill Sommerfeld. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * test SYS___getcwd. */ #include #include #include #include #include #include #include #include #include #include /* for MAXPATHLEN */ #include #include #include #include "getcwd.h" int main(int, char *[]); static void check1(char *dir, char *buf, char *calltext, int actual, int expected, int experr); static void time_old_getcwd(void); static void time_kern_getcwd(void); static void time_func(char *name, void (*func)(void)); static void test_speed(void); static void test___getcwd (void); static void test___getcwd_perms (void); static void test___getcwd_chroot(void); static void stress_test_getcwd(void); static void usage(char *progname); /* libc-private interface */ int __getcwd(char *, size_t); /* * test cases: * NULL pointer * broken pointer * zero-length buffer * negative length * one-character buffer * two-character buffer * full-length buffer * large (uncacheable) name in path. * deleted directory * after rename of parent. * permission failure. * good pointer near end of address space * really huge length * really large (multi-block) directories * chroot interactions: * chroot, at / inside the directory. * chroot, at some other inside directory. */ /* * test cases not yet done: * -o union mount * chroot interactions: * chroot to mounted directory. * (i.e., proc a: chroot /foo; sleep; * proc b: mount blort /foo) * concurrent with force-unmounting of filesystem. */ #define bigname "Funkelhausersteinweitz.SIPBADMIN.a" /* don't ask */ #define littlename "getcwdtest" #define othername "testgetcwd" static int verbose = 0; static int test = 1; static int fail = 0; static int pass = 0; static int sleepflag = 0; static uid_t altid = -1; static void check1 (dir, buf, calltext, actual, expected, experr) char *dir; char *buf; char *calltext; int actual, expected, experr; { int ntest = test++; if (actual != expected) { fprintf(stderr, "test %d: in %s, %s failed; expected %d, got %d\n", ntest, dir, calltext, expected, actual); if (actual < 0) perror("getcwd"); fail++; } else if ((expected == -1) && (errno != (experr))) { fprintf(stderr, "test %d: in %s, %s failed; expected error %d, got %d\n", ntest, dir, calltext, experr, errno); if (actual < 0) perror("getcwd"); fail++; } else if ((expected > 0) && (buf != NULL) && (strcmp (dir, buf) != 0)) { fprintf(stderr, "test %d: in %s, %s got wrong dir %s\n", ntest, dir, calltext, buf); fail++; } else { if (expected > 0) { char newbuf[1024]; char *cp = old_getcwd(newbuf, sizeof(newbuf)); if (cp == NULL) { fail++; fprintf(stderr, "test %d: in %s, old getcwd failed!\n", ntest, dir); } else if (strcmp(cp, buf)) { fail++; fprintf(stderr, "test %d: in %s, old_getcwd returned different dir %s\n", ntest, dir, cp); } } pass++; if (verbose) printf("test %d: in %s, %s passed\n", ntest, dir, calltext); } if (sleepflag) sleep(1); } int nloops = 100; void time_old_getcwd() { char result_buf[1024]; if (old_getcwd(result_buf, 1024) == NULL) { fprintf(stderr, "old_getcwd failed during timing test!\n"); perror("old_getcwd"); exit(1); } } void time_kern_getcwd() { char result_buf[1024]; if (__getcwd(result_buf, sizeof(result_buf)) < 0) { fprintf(stderr, "getcwd failed during timing test!"); perror("getcwd"); exit(1); } } static void time_func(name, func) char *name; void (*func)(void); { struct timeval before, after; double delta_t; int i; chdir ("/usr/share/examples/emul/ultrix/etc"); gettimeofday(&before, 0); for (i=0; i