xref: /netbsd-src/tests/lib/libc/gen/t_realpath.c (revision 015162ac4e3b6f6a70c963273fb459ee837176af)
1*015162acSnjoly /* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */
26aa27f04Sjruoho 
36aa27f04Sjruoho /*-
46aa27f04Sjruoho  * Copyright (c) 2012 The NetBSD Foundation, Inc.
56aa27f04Sjruoho  * All rights reserved.
66aa27f04Sjruoho  *
76aa27f04Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
86aa27f04Sjruoho  * by Jukka Ruohonen.
96aa27f04Sjruoho  *
106aa27f04Sjruoho  * Redistribution and use in source and binary forms, with or without
116aa27f04Sjruoho  * modification, are permitted provided that the following conditions
126aa27f04Sjruoho  * are met:
136aa27f04Sjruoho  * 1. Redistributions of source code must retain the above copyright
146aa27f04Sjruoho  *    notice, this list of conditions and the following disclaimer.
156aa27f04Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
166aa27f04Sjruoho  *    notice, this list of conditions and the following disclaimer in the
176aa27f04Sjruoho  *    documentation and/or other materials provided with the distribution.
186aa27f04Sjruoho  *
196aa27f04Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
206aa27f04Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
216aa27f04Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
226aa27f04Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
236aa27f04Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
246aa27f04Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
256aa27f04Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
266aa27f04Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
276aa27f04Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
286aa27f04Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
296aa27f04Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
306aa27f04Sjruoho  */
316aa27f04Sjruoho #include <sys/cdefs.h>
32*015162acSnjoly __RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $");
336aa27f04Sjruoho 
346aa27f04Sjruoho #include <sys/param.h>
356aa27f04Sjruoho 
366aa27f04Sjruoho #include <atf-c.h>
376aa27f04Sjruoho #include <fcntl.h>
386aa27f04Sjruoho #include <stdio.h>
396aa27f04Sjruoho #include <stdlib.h>
406aa27f04Sjruoho #include <string.h>
416aa27f04Sjruoho #include <unistd.h>
426aa27f04Sjruoho 
436aa27f04Sjruoho static const struct {
446aa27f04Sjruoho 	const char *path;
456aa27f04Sjruoho 	const char *result;
466aa27f04Sjruoho } paths[] = {
476aa27f04Sjruoho 
486aa27f04Sjruoho 	{ "/",			"/"		},
496aa27f04Sjruoho 	{ "///////",		"/"		},
506aa27f04Sjruoho 	{ "",			NULL		},
516aa27f04Sjruoho 	{ "       ",		NULL		},
526aa27f04Sjruoho 	{ "/      ",		NULL		},
536aa27f04Sjruoho 	{ "      /",		NULL		},
546aa27f04Sjruoho 	{ "/etc///",		"/etc"		},
556aa27f04Sjruoho 	{ "///////etc",		"/etc"		},
566aa27f04Sjruoho 	{ "/a/b/c/d/e",		NULL		},
576aa27f04Sjruoho 	{ "    /usr/bin	   ",	NULL		},
586aa27f04Sjruoho 	{ "\\//////usr//bin",	NULL		},
596aa27f04Sjruoho 	{ "//usr//bin//",	"/usr/bin"	},
606aa27f04Sjruoho 	{ "//////usr//bin//",	"/usr/bin"	},
616aa27f04Sjruoho 	{ "/usr/bin//////////", "/usr/bin"	},
626aa27f04Sjruoho };
636aa27f04Sjruoho 
646aa27f04Sjruoho ATF_TC(realpath_basic);
ATF_TC_HEAD(realpath_basic,tc)656aa27f04Sjruoho ATF_TC_HEAD(realpath_basic, tc)
666aa27f04Sjruoho {
676aa27f04Sjruoho 	atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)");
686aa27f04Sjruoho }
696aa27f04Sjruoho 
ATF_TC_BODY(realpath_basic,tc)706aa27f04Sjruoho ATF_TC_BODY(realpath_basic, tc)
716aa27f04Sjruoho {
726aa27f04Sjruoho 	char buf[MAXPATHLEN];
736aa27f04Sjruoho 	char *ptr;
746aa27f04Sjruoho 	size_t i;
756aa27f04Sjruoho 
766aa27f04Sjruoho 	for (i = 0; i < __arraycount(paths); i++) {
776aa27f04Sjruoho 
786aa27f04Sjruoho 		(void)memset(buf, '\0', sizeof(buf));
796aa27f04Sjruoho 
806aa27f04Sjruoho 		ptr = realpath(paths[i].path, buf);
816aa27f04Sjruoho 
826aa27f04Sjruoho 		if (ptr == NULL && paths[i].result == NULL)
836aa27f04Sjruoho 			continue;
846aa27f04Sjruoho 
856aa27f04Sjruoho 		if (ptr == NULL && paths[i].result != NULL)
866aa27f04Sjruoho 			atf_tc_fail("realpath failed for '%s'", paths[i].path);
876aa27f04Sjruoho 
886aa27f04Sjruoho 		if (strcmp(paths[i].result, buf) != 0)
896aa27f04Sjruoho 			atf_tc_fail("expected '%s', got '%s'",
906aa27f04Sjruoho 			    paths[i].result, buf);
916aa27f04Sjruoho 	}
926aa27f04Sjruoho }
936aa27f04Sjruoho 
946aa27f04Sjruoho ATF_TC(realpath_huge);
ATF_TC_HEAD(realpath_huge,tc)956aa27f04Sjruoho ATF_TC_HEAD(realpath_huge, tc)
966aa27f04Sjruoho {
976aa27f04Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)");
986aa27f04Sjruoho }
996aa27f04Sjruoho 
ATF_TC_BODY(realpath_huge,tc)1006aa27f04Sjruoho ATF_TC_BODY(realpath_huge, tc)
1016aa27f04Sjruoho {
1026aa27f04Sjruoho 	char result[MAXPATHLEN] = { 0 };
1036aa27f04Sjruoho 	char buffer[MAXPATHLEN] = { 0 };
1046aa27f04Sjruoho 
105*015162acSnjoly 	(void)memset(buffer, '/', sizeof(buffer) - 1);
1066aa27f04Sjruoho 
1076aa27f04Sjruoho 	ATF_CHECK(realpath(buffer, result) != NULL);
1086aa27f04Sjruoho 	ATF_CHECK(strlen(result) == 1);
1096aa27f04Sjruoho 	ATF_CHECK(result[0] == '/');
1106aa27f04Sjruoho }
1116aa27f04Sjruoho 
1126aa27f04Sjruoho ATF_TC(realpath_symlink);
ATF_TC_HEAD(realpath_symlink,tc)1136aa27f04Sjruoho ATF_TC_HEAD(realpath_symlink, tc)
1146aa27f04Sjruoho {
1156aa27f04Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)");
1166aa27f04Sjruoho }
1176aa27f04Sjruoho 
ATF_TC_BODY(realpath_symlink,tc)1186aa27f04Sjruoho ATF_TC_BODY(realpath_symlink, tc)
1196aa27f04Sjruoho {
1206aa27f04Sjruoho 	char path[MAXPATHLEN] = { 0 };
1216aa27f04Sjruoho 	char slnk[MAXPATHLEN] = { 0 };
1226aa27f04Sjruoho 	char resb[MAXPATHLEN] = { 0 };
1236aa27f04Sjruoho 	int fd;
1246aa27f04Sjruoho 
1256aa27f04Sjruoho 	(void)getcwd(path, sizeof(path));
1266aa27f04Sjruoho 	(void)getcwd(slnk, sizeof(slnk));
1276aa27f04Sjruoho 
1286aa27f04Sjruoho 	(void)strlcat(path, "/realpath", sizeof(path));
1296aa27f04Sjruoho 	(void)strlcat(slnk, "/symbolic", sizeof(slnk));
1306aa27f04Sjruoho 
1316aa27f04Sjruoho 	fd = open(path, O_RDONLY | O_CREAT, 0600);
1326aa27f04Sjruoho 
1336aa27f04Sjruoho 	ATF_REQUIRE(fd >= 0);
1346aa27f04Sjruoho 	ATF_REQUIRE(symlink(path, slnk) == 0);
1356aa27f04Sjruoho 	ATF_REQUIRE(close(fd) == 0);
1366aa27f04Sjruoho 
1376aa27f04Sjruoho 	ATF_REQUIRE(realpath(slnk, resb) != NULL);
1386aa27f04Sjruoho 	ATF_REQUIRE(strcmp(resb, path) == 0);
1396aa27f04Sjruoho 
1406aa27f04Sjruoho 	ATF_REQUIRE(unlink(path) == 0);
1416aa27f04Sjruoho 	ATF_REQUIRE(unlink(slnk) == 0);
1426aa27f04Sjruoho }
1436aa27f04Sjruoho 
ATF_TP_ADD_TCS(tp)1446aa27f04Sjruoho ATF_TP_ADD_TCS(tp)
1456aa27f04Sjruoho {
1466aa27f04Sjruoho 
1476aa27f04Sjruoho 	ATF_TP_ADD_TC(tp, realpath_basic);
1486aa27f04Sjruoho 	ATF_TP_ADD_TC(tp, realpath_huge);
1496aa27f04Sjruoho 	ATF_TP_ADD_TC(tp, realpath_symlink);
1506aa27f04Sjruoho 
1516aa27f04Sjruoho 	return atf_no_error();
1526aa27f04Sjruoho }
153