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