1 1.3 jruoho /* $NetBSD: h_cwd.c,v 1.3 2012/04/17 09:23:21 jruoho Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * Redistribution and use in source and binary forms, with or without 8 1.1 pooka * modification, are permitted provided that the following conditions 9 1.1 pooka * are met: 10 1.1 pooka * 1. Redistributions of source code must retain the above copyright 11 1.1 pooka * notice, this list of conditions and the following disclaimer. 12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 pooka * notice, this list of conditions and the following disclaimer in the 14 1.1 pooka * documentation and/or other materials provided with the distribution. 15 1.1 pooka * 16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 1.1 pooka * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 1.1 pooka * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 1.1 pooka * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 pooka * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 1.1 pooka * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 1.1 pooka * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 1.1 pooka * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 1.1 pooka * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 1.1 pooka * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 pooka */ 29 1.1 pooka 30 1.1 pooka #include <sys/types.h> 31 1.1 pooka #include <sys/stat.h> 32 1.1 pooka 33 1.1 pooka #include <err.h> 34 1.1 pooka #include <errno.h> 35 1.2 pooka #include <fcntl.h> 36 1.3 jruoho #include <stdlib.h> 37 1.1 pooka #include <string.h> 38 1.1 pooka #include <unistd.h> 39 1.1 pooka 40 1.2 pooka static const char *prefix; 41 1.2 pooka static size_t prefixlen; 42 1.2 pooka static char buf[1024]; 43 1.2 pooka static char pwd[1024]; 44 1.2 pooka 45 1.2 pooka static const char * 46 1.2 pooka makepath(const char *tail) 47 1.2 pooka { 48 1.2 pooka 49 1.2 pooka strcpy(buf, prefix); 50 1.2 pooka if (prefix[prefixlen-1] != '/') 51 1.2 pooka strcat(buf, "/"); 52 1.2 pooka strcat(buf, tail); 53 1.2 pooka 54 1.2 pooka return buf; 55 1.2 pooka } 56 1.2 pooka 57 1.2 pooka static void 58 1.2 pooka dochdir(const char *path, const char *errmsg) 59 1.2 pooka { 60 1.2 pooka 61 1.2 pooka if (chdir(path) == -1) 62 1.3 jruoho err(EXIT_FAILURE, "%s", errmsg); 63 1.2 pooka } 64 1.2 pooka 65 1.2 pooka static void 66 1.2 pooka dofchdir(const char *path, const char *errmsg) 67 1.2 pooka { 68 1.2 pooka int fd; 69 1.2 pooka 70 1.2 pooka fd = open(path, O_RDONLY); 71 1.2 pooka if (fd == -1) 72 1.3 jruoho err(EXIT_FAILURE, "open %s", errmsg); 73 1.2 pooka if (fchdir(fd) == -1) 74 1.3 jruoho err(EXIT_FAILURE, "fchdir %s", errmsg); 75 1.2 pooka close(fd); 76 1.2 pooka } 77 1.2 pooka static void (*thechdir)(const char *, const char *); 78 1.2 pooka 79 1.2 pooka static void 80 1.2 pooka simple(void) 81 1.1 pooka { 82 1.1 pooka 83 1.2 pooka thechdir(prefix, "chdir1"); 84 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 85 1.3 jruoho err(EXIT_FAILURE, "getcwd1"); 86 1.2 pooka if (strcmp(pwd, prefix) != 0) 87 1.3 jruoho errx(EXIT_FAILURE, "strcmp1"); 88 1.1 pooka 89 1.1 pooka if (mkdir("dir", 0777) == -1) 90 1.3 jruoho err(EXIT_FAILURE, "mkdir2"); 91 1.2 pooka thechdir("dir", "chdir2"); 92 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 93 1.3 jruoho err(EXIT_FAILURE, "getcwd2"); 94 1.2 pooka if (strcmp(pwd, makepath("dir")) != 0) 95 1.3 jruoho errx(EXIT_FAILURE, "strcmp2"); 96 1.1 pooka 97 1.1 pooka if (mkdir("dir", 0777) == -1) 98 1.3 jruoho err(EXIT_FAILURE, "mkdir3"); 99 1.2 pooka thechdir("dir", "chdir3"); 100 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 101 1.3 jruoho err(EXIT_FAILURE, "getcwd3"); 102 1.2 pooka if (strcmp(pwd, makepath("dir/dir")) != 0) 103 1.3 jruoho errx(EXIT_FAILURE, "strcmp3"); 104 1.1 pooka 105 1.2 pooka thechdir("..", "chdir4"); 106 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 107 1.3 jruoho err(EXIT_FAILURE, "getcwd4"); 108 1.2 pooka if (strcmp(pwd, makepath("dir")) != 0) 109 1.3 jruoho errx(EXIT_FAILURE, "strcmp4"); 110 1.1 pooka 111 1.2 pooka 112 1.2 pooka thechdir("../../../../../../..", "chdir5"); 113 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 114 1.3 jruoho err(EXIT_FAILURE, "getcwd5"); 115 1.2 pooka if (strcmp(pwd, prefix) != 0) 116 1.3 jruoho errx(EXIT_FAILURE, "strcmp5"); 117 1.1 pooka 118 1.2 pooka thechdir("/", "chdir6"); 119 1.1 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 120 1.3 jruoho err(EXIT_FAILURE, "getcwd6"); 121 1.1 pooka if (strcmp(pwd, "/") != 0) 122 1.3 jruoho errx(EXIT_FAILURE, "strcmp6"); 123 1.2 pooka } 124 1.2 pooka 125 1.2 pooka static void 126 1.2 pooka symlinktest(void) 127 1.2 pooka { 128 1.2 pooka 129 1.2 pooka thechdir(prefix, "chdir1"); 130 1.2 pooka if (mkdir("adir", 0777) == -1) 131 1.3 jruoho err(EXIT_FAILURE, "mkdir1"); 132 1.2 pooka if (mkdir("anotherdir", 0777) == -1) 133 1.3 jruoho err(EXIT_FAILURE, "mkdir2"); 134 1.2 pooka 135 1.2 pooka if (symlink("/adir", "anotherdir/lincthesink") == -1) 136 1.3 jruoho err(EXIT_FAILURE, "symlink"); 137 1.2 pooka 138 1.2 pooka thechdir("anotherdir/lincthesink", "chdir2"); 139 1.2 pooka if (getcwd(pwd, sizeof(pwd)) == NULL) 140 1.3 jruoho err(EXIT_FAILURE, "getcwd"); 141 1.2 pooka if (strcmp(pwd, makepath("adir")) != 0) 142 1.3 jruoho errx(EXIT_FAILURE, "strcmp"); 143 1.2 pooka } 144 1.2 pooka 145 1.2 pooka int 146 1.2 pooka main(int argc, char *argv[]) 147 1.2 pooka { 148 1.2 pooka 149 1.2 pooka if (argc != 4) 150 1.2 pooka errx(1, "usage"); 151 1.2 pooka 152 1.2 pooka prefix = argv[1]; 153 1.2 pooka prefixlen = strlen(argv[1]); 154 1.2 pooka 155 1.2 pooka if (strcmp(argv[3], "chdir") == 0) 156 1.2 pooka thechdir = dochdir; 157 1.2 pooka else if (strcmp(argv[3], "fchdir") == 0) 158 1.2 pooka thechdir = dofchdir; 159 1.2 pooka else 160 1.3 jruoho errx(EXIT_FAILURE, "invalid chdir type"); 161 1.2 pooka 162 1.2 pooka if (strcmp(argv[2], "simple") == 0) 163 1.2 pooka simple(); 164 1.2 pooka if (strcmp(argv[2], "symlink") == 0) 165 1.2 pooka symlinktest(); 166 1.1 pooka 167 1.3 jruoho return EXIT_SUCCESS; 168 1.1 pooka } 169