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 #include <fcntl.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 static const struct { 44 const char *path; 45 const char *result; 46 } paths[] = { 47 48 { "/", "/" }, 49 { "///////", "/" }, 50 { "", NULL }, 51 { " ", NULL }, 52 { "/ ", NULL }, 53 { " /", NULL }, 54 { "/etc///", "/etc" }, 55 { "///////etc", "/etc" }, 56 { "/a/b/c/d/e", NULL }, 57 { " /usr/bin ", NULL }, 58 { "\\//////usr//bin", NULL }, 59 { "//usr//bin//", "/usr/bin" }, 60 { "//////usr//bin//", "/usr/bin" }, 61 { "/usr/bin//////////", "/usr/bin" }, 62 }; 63 64 ATF_TC(realpath_basic); 65 ATF_TC_HEAD(realpath_basic, tc) 66 { 67 atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); 68 } 69 70 ATF_TC_BODY(realpath_basic, tc) 71 { 72 char buf[MAXPATHLEN]; 73 char *ptr; 74 size_t i; 75 76 for (i = 0; i < __arraycount(paths); i++) { 77 78 (void)memset(buf, '\0', sizeof(buf)); 79 80 ptr = realpath(paths[i].path, buf); 81 82 if (ptr == NULL && paths[i].result == NULL) 83 continue; 84 85 if (ptr == NULL && paths[i].result != NULL) 86 atf_tc_fail("realpath failed for '%s'", paths[i].path); 87 88 if (strcmp(paths[i].result, buf) != 0) 89 atf_tc_fail("expected '%s', got '%s'", 90 paths[i].result, buf); 91 } 92 } 93 94 ATF_TC(realpath_huge); 95 ATF_TC_HEAD(realpath_huge, tc) 96 { 97 atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); 98 } 99 100 ATF_TC_BODY(realpath_huge, tc) 101 { 102 char result[MAXPATHLEN] = { 0 }; 103 char buffer[MAXPATHLEN] = { 0 }; 104 105 (void)memset(buffer, '/', sizeof(buffer) - 1); 106 107 ATF_CHECK(realpath(buffer, result) != NULL); 108 ATF_CHECK(strlen(result) == 1); 109 ATF_CHECK(result[0] == '/'); 110 } 111 112 ATF_TC(realpath_symlink); 113 ATF_TC_HEAD(realpath_symlink, tc) 114 { 115 atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); 116 } 117 118 ATF_TC_BODY(realpath_symlink, tc) 119 { 120 char path[MAXPATHLEN] = { 0 }; 121 char slnk[MAXPATHLEN] = { 0 }; 122 char resb[MAXPATHLEN] = { 0 }; 123 int fd; 124 125 (void)getcwd(path, sizeof(path)); 126 (void)getcwd(slnk, sizeof(slnk)); 127 128 (void)strlcat(path, "/realpath", sizeof(path)); 129 (void)strlcat(slnk, "/symbolic", sizeof(slnk)); 130 131 fd = open(path, O_RDONLY | O_CREAT, 0600); 132 133 ATF_REQUIRE(fd >= 0); 134 ATF_REQUIRE(symlink(path, slnk) == 0); 135 ATF_REQUIRE(close(fd) == 0); 136 137 ATF_REQUIRE(realpath(slnk, resb) != NULL); 138 ATF_REQUIRE(strcmp(resb, path) == 0); 139 140 ATF_REQUIRE(unlink(path) == 0); 141 ATF_REQUIRE(unlink(slnk) == 0); 142 } 143 144 ATF_TP_ADD_TCS(tp) 145 { 146 147 ATF_TP_ADD_TC(tp, realpath_basic); 148 ATF_TP_ADD_TC(tp, realpath_huge); 149 ATF_TP_ADD_TC(tp, realpath_symlink); 150 151 return atf_no_error(); 152 } 153