1*f95573c2Sjruoho /* $NetBSD: h_cwd.c,v 1.3 2012/04/17 09:23:21 jruoho Exp $ */
244ff4bdcSpooka
344ff4bdcSpooka /*-
444ff4bdcSpooka * Copyright (c) 2011 The NetBSD Foundation, Inc.
544ff4bdcSpooka * All rights reserved.
644ff4bdcSpooka *
744ff4bdcSpooka * Redistribution and use in source and binary forms, with or without
844ff4bdcSpooka * modification, are permitted provided that the following conditions
944ff4bdcSpooka * are met:
1044ff4bdcSpooka * 1. Redistributions of source code must retain the above copyright
1144ff4bdcSpooka * notice, this list of conditions and the following disclaimer.
1244ff4bdcSpooka * 2. Redistributions in binary form must reproduce the above copyright
1344ff4bdcSpooka * notice, this list of conditions and the following disclaimer in the
1444ff4bdcSpooka * documentation and/or other materials provided with the distribution.
1544ff4bdcSpooka *
1644ff4bdcSpooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
1744ff4bdcSpooka * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1844ff4bdcSpooka * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1944ff4bdcSpooka * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2044ff4bdcSpooka * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
2144ff4bdcSpooka * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2244ff4bdcSpooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2344ff4bdcSpooka * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2444ff4bdcSpooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2544ff4bdcSpooka * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2644ff4bdcSpooka * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2744ff4bdcSpooka * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2844ff4bdcSpooka */
2944ff4bdcSpooka
3044ff4bdcSpooka #include <sys/types.h>
3144ff4bdcSpooka #include <sys/stat.h>
3244ff4bdcSpooka
3344ff4bdcSpooka #include <err.h>
3444ff4bdcSpooka #include <errno.h>
3591a9bf94Spooka #include <fcntl.h>
36*f95573c2Sjruoho #include <stdlib.h>
3744ff4bdcSpooka #include <string.h>
3844ff4bdcSpooka #include <unistd.h>
3944ff4bdcSpooka
4091a9bf94Spooka static const char *prefix;
4191a9bf94Spooka static size_t prefixlen;
4291a9bf94Spooka static char buf[1024];
4391a9bf94Spooka static char pwd[1024];
4444ff4bdcSpooka
4591a9bf94Spooka static const char *
makepath(const char * tail)4691a9bf94Spooka makepath(const char *tail)
4791a9bf94Spooka {
4891a9bf94Spooka
4991a9bf94Spooka strcpy(buf, prefix);
5091a9bf94Spooka if (prefix[prefixlen-1] != '/')
5191a9bf94Spooka strcat(buf, "/");
5291a9bf94Spooka strcat(buf, tail);
5391a9bf94Spooka
5491a9bf94Spooka return buf;
5591a9bf94Spooka }
5691a9bf94Spooka
5791a9bf94Spooka static void
dochdir(const char * path,const char * errmsg)5891a9bf94Spooka dochdir(const char *path, const char *errmsg)
5991a9bf94Spooka {
6091a9bf94Spooka
6191a9bf94Spooka if (chdir(path) == -1)
62*f95573c2Sjruoho err(EXIT_FAILURE, "%s", errmsg);
6391a9bf94Spooka }
6491a9bf94Spooka
6591a9bf94Spooka static void
dofchdir(const char * path,const char * errmsg)6691a9bf94Spooka dofchdir(const char *path, const char *errmsg)
6791a9bf94Spooka {
6891a9bf94Spooka int fd;
6991a9bf94Spooka
7091a9bf94Spooka fd = open(path, O_RDONLY);
7191a9bf94Spooka if (fd == -1)
72*f95573c2Sjruoho err(EXIT_FAILURE, "open %s", errmsg);
7391a9bf94Spooka if (fchdir(fd) == -1)
74*f95573c2Sjruoho err(EXIT_FAILURE, "fchdir %s", errmsg);
7591a9bf94Spooka close(fd);
7691a9bf94Spooka }
7791a9bf94Spooka static void (*thechdir)(const char *, const char *);
7891a9bf94Spooka
7991a9bf94Spooka static void
simple(void)8091a9bf94Spooka simple(void)
8191a9bf94Spooka {
8291a9bf94Spooka
8391a9bf94Spooka thechdir(prefix, "chdir1");
8444ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
85*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd1");
8691a9bf94Spooka if (strcmp(pwd, prefix) != 0)
87*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp1");
8844ff4bdcSpooka
8944ff4bdcSpooka if (mkdir("dir", 0777) == -1)
90*f95573c2Sjruoho err(EXIT_FAILURE, "mkdir2");
9191a9bf94Spooka thechdir("dir", "chdir2");
9244ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
93*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd2");
9491a9bf94Spooka if (strcmp(pwd, makepath("dir")) != 0)
95*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp2");
9644ff4bdcSpooka
9744ff4bdcSpooka if (mkdir("dir", 0777) == -1)
98*f95573c2Sjruoho err(EXIT_FAILURE, "mkdir3");
9991a9bf94Spooka thechdir("dir", "chdir3");
10044ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
101*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd3");
10291a9bf94Spooka if (strcmp(pwd, makepath("dir/dir")) != 0)
103*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp3");
10444ff4bdcSpooka
10591a9bf94Spooka thechdir("..", "chdir4");
10644ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
107*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd4");
10891a9bf94Spooka if (strcmp(pwd, makepath("dir")) != 0)
109*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp4");
11044ff4bdcSpooka
11191a9bf94Spooka
11291a9bf94Spooka thechdir("../../../../../../..", "chdir5");
11344ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
114*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd5");
11591a9bf94Spooka if (strcmp(pwd, prefix) != 0)
116*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp5");
11744ff4bdcSpooka
11891a9bf94Spooka thechdir("/", "chdir6");
11944ff4bdcSpooka if (getcwd(pwd, sizeof(pwd)) == NULL)
120*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd6");
12144ff4bdcSpooka if (strcmp(pwd, "/") != 0)
122*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp6");
12391a9bf94Spooka }
12491a9bf94Spooka
12591a9bf94Spooka static void
symlinktest(void)12691a9bf94Spooka symlinktest(void)
12791a9bf94Spooka {
12891a9bf94Spooka
12991a9bf94Spooka thechdir(prefix, "chdir1");
13091a9bf94Spooka if (mkdir("adir", 0777) == -1)
131*f95573c2Sjruoho err(EXIT_FAILURE, "mkdir1");
13291a9bf94Spooka if (mkdir("anotherdir", 0777) == -1)
133*f95573c2Sjruoho err(EXIT_FAILURE, "mkdir2");
13491a9bf94Spooka
13591a9bf94Spooka if (symlink("/adir", "anotherdir/lincthesink") == -1)
136*f95573c2Sjruoho err(EXIT_FAILURE, "symlink");
13791a9bf94Spooka
13891a9bf94Spooka thechdir("anotherdir/lincthesink", "chdir2");
13991a9bf94Spooka if (getcwd(pwd, sizeof(pwd)) == NULL)
140*f95573c2Sjruoho err(EXIT_FAILURE, "getcwd");
14191a9bf94Spooka if (strcmp(pwd, makepath("adir")) != 0)
142*f95573c2Sjruoho errx(EXIT_FAILURE, "strcmp");
14391a9bf94Spooka }
14491a9bf94Spooka
14591a9bf94Spooka int
main(int argc,char * argv[])14691a9bf94Spooka main(int argc, char *argv[])
14791a9bf94Spooka {
14891a9bf94Spooka
14991a9bf94Spooka if (argc != 4)
15091a9bf94Spooka errx(1, "usage");
15191a9bf94Spooka
15291a9bf94Spooka prefix = argv[1];
15391a9bf94Spooka prefixlen = strlen(argv[1]);
15491a9bf94Spooka
15591a9bf94Spooka if (strcmp(argv[3], "chdir") == 0)
15691a9bf94Spooka thechdir = dochdir;
15791a9bf94Spooka else if (strcmp(argv[3], "fchdir") == 0)
15891a9bf94Spooka thechdir = dofchdir;
15991a9bf94Spooka else
160*f95573c2Sjruoho errx(EXIT_FAILURE, "invalid chdir type");
16191a9bf94Spooka
16291a9bf94Spooka if (strcmp(argv[2], "simple") == 0)
16391a9bf94Spooka simple();
16491a9bf94Spooka if (strcmp(argv[2], "symlink") == 0)
16591a9bf94Spooka symlinktest();
16644ff4bdcSpooka
167*f95573c2Sjruoho return EXIT_SUCCESS;
16844ff4bdcSpooka }
169