1 /* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */ 2 3 /*- 4 * Copyright (c) 2012 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jukka Ruohonen. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $"); 33 34 #include <sys/param.h> 35 36 #include <atf-c.h> 37 #ifdef __FreeBSD__ 38 #include <errno.h> 39 #endif 40 #include <fcntl.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46 static const struct { 47 const char *path; 48 const char *result; 49 } paths[] = { 50 51 { "/", "/" }, 52 { "///////", "/" }, 53 { "", NULL }, 54 { " ", NULL }, 55 { "/ ", NULL }, 56 { " /", NULL }, 57 { "/etc///", "/etc" }, 58 { "///////etc", "/etc" }, 59 { "/a/b/c/d/e", NULL }, 60 { " /usr/bin ", NULL }, 61 { "\\//////usr//bin", NULL }, 62 { "//usr//bin//", "/usr/bin" }, 63 { "//////usr//bin//", "/usr/bin" }, 64 { "/usr/bin//////////", "/usr/bin" }, 65 }; 66 67 ATF_TC(realpath_basic); 68 ATF_TC_HEAD(realpath_basic, tc) 69 { 70 atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); 71 } 72 73 ATF_TC_BODY(realpath_basic, tc) 74 { 75 char buf[MAXPATHLEN]; 76 char *ptr; 77 size_t i; 78 79 for (i = 0; i < __arraycount(paths); i++) { 80 81 (void)memset(buf, '\0', sizeof(buf)); 82 83 ptr = realpath(paths[i].path, buf); 84 85 if (ptr == NULL && paths[i].result == NULL) 86 continue; 87 88 if (ptr == NULL && paths[i].result != NULL) 89 atf_tc_fail("realpath failed for '%s'", paths[i].path); 90 91 if (strcmp(paths[i].result, buf) != 0) 92 atf_tc_fail("expected '%s', got '%s'", 93 paths[i].result, buf); 94 } 95 } 96 97 ATF_TC(realpath_huge); 98 ATF_TC_HEAD(realpath_huge, tc) 99 { 100 atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); 101 } 102 103 ATF_TC_BODY(realpath_huge, tc) 104 { 105 char result[MAXPATHLEN] = { 0 }; 106 char buffer[MAXPATHLEN] = { 0 }; 107 108 (void)memset(buffer, '/', sizeof(buffer) - 1); 109 110 ATF_CHECK(realpath(buffer, result) != NULL); 111 ATF_CHECK(strlen(result) == 1); 112 ATF_CHECK(result[0] == '/'); 113 } 114 115 ATF_TC(realpath_symlink); 116 ATF_TC_HEAD(realpath_symlink, tc) 117 { 118 atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); 119 } 120 121 ATF_TC_BODY(realpath_symlink, tc) 122 { 123 char path[MAXPATHLEN] = { 0 }; 124 char slnk[MAXPATHLEN] = { 0 }; 125 char resb[MAXPATHLEN] = { 0 }; 126 int fd; 127 128 #ifdef __FreeBSD__ 129 ATF_REQUIRE_MSG(getcwd(path, sizeof(path)) != NULL, 130 "getcwd(path) failed: %s", strerror(errno)); 131 ATF_REQUIRE_MSG(getcwd(slnk, sizeof(slnk)) != NULL, 132 "getcwd(slnk) failed: %s", strerror(errno)); 133 #else 134 (void)getcwd(path, sizeof(path)); 135 (void)getcwd(slnk, sizeof(slnk)); 136 #endif 137 138 (void)strlcat(path, "/realpath", sizeof(path)); 139 (void)strlcat(slnk, "/symbolic", sizeof(slnk)); 140 141 fd = open(path, O_RDONLY | O_CREAT, 0600); 142 143 ATF_REQUIRE(fd >= 0); 144 ATF_REQUIRE(symlink(path, slnk) == 0); 145 ATF_REQUIRE(close(fd) == 0); 146 147 ATF_REQUIRE(realpath(slnk, resb) != NULL); 148 ATF_REQUIRE(strcmp(resb, path) == 0); 149 150 ATF_REQUIRE(unlink(path) == 0); 151 ATF_REQUIRE(unlink(slnk) == 0); 152 } 153 154 ATF_TP_ADD_TCS(tp) 155 { 156 157 ATF_TP_ADD_TC(tp, realpath_basic); 158 ATF_TP_ADD_TC(tp, realpath_huge); 159 ATF_TP_ADD_TC(tp, realpath_symlink); 160 161 return atf_no_error(); 162 } 163