t_access.c revision 273391
119370Spst/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ 219370Spst 319370Spst/*- 419370Spst * Copyright (c) 2011 The NetBSD Foundation, Inc. 519370Spst * All rights reserved. 619370Spst * 719370Spst * This code is derived from software contributed to The NetBSD Foundation 819370Spst * by Jukka Ruohonen. 919370Spst * 1019370Spst * Redistribution and use in source and binary forms, with or without 1119370Spst * modification, are permitted provided that the following conditions 1219370Spst * are met: 1319370Spst * 1. Redistributions of source code must retain the above copyright 1419370Spst * notice, this list of conditions and the following disclaimer. 1519370Spst * 2. Redistributions in binary form must reproduce the above copyright 1619370Spst * notice, this list of conditions and the following disclaimer in the 1719370Spst * documentation and/or other materials provided with the distribution. 1819370Spst * 1919370Spst * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2019370Spst * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2119370Spst * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2219370Spst * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2319370Spst * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2419370Spst * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2519370Spst * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2619370Spst * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2719370Spst * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2819370Spst * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2919370Spst * POSSIBILITY OF SUCH DAMAGE. 3019370Spst */ 3119370Spst#include <sys/cdefs.h> 3219370Spst__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); 3319370Spst 3419370Spst#include <errno.h> 3519370Spst#include <fcntl.h> 3619370Spst#include <limits.h> 3719370Spst#include <stdint.h> 3819370Spst#include <stdlib.h> 3919370Spst#include <unistd.h> 4019370Spst 4119370Spst#include <atf-c.h> 4219370Spst 4319370Spst#if defined(__FreeBSD__) 4419370Spst#include <sys/stat.h> 4519370Spst#endif 4619370Spst 4719370Spststatic const char path[] = "access"; 4819370Spststatic const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; 4919370Spst 5019370SpstATF_TC_WITH_CLEANUP(access_access); 5119370SpstATF_TC_HEAD(access_access, tc) 5219370Spst{ 5319370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES"); 5419370Spst atf_tc_set_md_var(tc, "require.user", "unprivileged"); 5519370Spst} 5619370Spst 5719370SpstATF_TC_BODY(access_access, tc) 5819370Spst{ 5919370Spst const int perm[3] = { 0200, 0400, 0000 }; 6019370Spst size_t i; 6119370Spst int fd; 6219370Spst 6319370Spst fd = open(path, O_RDONLY | O_CREAT); 6419370Spst 6519370Spst if (fd < 0) 6619370Spst return; 6719370Spst 6819370Spst for (i = 0; i < __arraycount(mode) - 1; i++) { 6919370Spst 7019370Spst ATF_REQUIRE(fchmod(fd, perm[i]) == 0); 7119370Spst 7219370Spst errno = 0; 7319370Spst 7419370Spst ATF_REQUIRE(access(path, mode[i]) != 0); 7519370Spst ATF_REQUIRE(errno == EACCES); 7619370Spst } 7719370Spst 7819370Spst ATF_REQUIRE(close(fd) == 0); 7919370Spst} 8019370Spst 8119370SpstATF_TC_CLEANUP(access_access, tc) 8219370Spst{ 8319370Spst (void)unlink(path); 8419370Spst} 8519370Spst 8619370SpstATF_TC(access_fault); 8719370SpstATF_TC_HEAD(access_fault, tc) 8819370Spst{ 8919370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT"); 9019370Spst} 9119370Spst 9219370SpstATF_TC_BODY(access_fault, tc) 9319370Spst{ 9419370Spst size_t i; 9519370Spst 9619370Spst for (i = 0; i < __arraycount(mode); i++) { 9719370Spst 9819370Spst errno = 0; 9919370Spst 10019370Spst ATF_REQUIRE(access(NULL, mode[i]) != 0); 10119370Spst ATF_REQUIRE(errno == EFAULT); 10219370Spst 10319370Spst errno = 0; 10419370Spst 10519370Spst ATF_REQUIRE(access((char *)-1, mode[i]) != 0); 10619370Spst ATF_REQUIRE(errno == EFAULT); 10719370Spst } 10819370Spst} 10919370Spst 11019370SpstATF_TC(access_inval); 11119370SpstATF_TC_HEAD(access_inval, tc) 11219370Spst{ 11319370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL"); 11419370Spst} 11546283Sdfr 11646283SdfrATF_TC_BODY(access_inval, tc) 11746283Sdfr{ 11846283Sdfr 11919370Spst errno = 0; 12019370Spst 12119370Spst ATF_REQUIRE(access("/usr", -1) != 0); 12219370Spst ATF_REQUIRE(errno == EINVAL); 12319370Spst} 12419370Spst 12519370SpstATF_TC(access_notdir); 12619370SpstATF_TC_HEAD(access_notdir, tc) 12719370Spst{ 12819370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR"); 12919370Spst} 13019370Spst 13119370SpstATF_TC_BODY(access_notdir, tc) 13219370Spst{ 13319370Spst size_t i; 13419370Spst 13519370Spst for (i = 0; i < __arraycount(mode); i++) { 13619370Spst 13719370Spst errno = 0; 13819370Spst 13919370Spst /* 14046283Sdfr * IEEE Std 1003.1-2008 about ENOTDIR: 14146283Sdfr * 14246283Sdfr * "A component of the path prefix is not a directory, 14319370Spst * or the path argument contains at least one non-<slash> 14419370Spst * character and ends with one or more trailing <slash> 14519370Spst * characters and the last pathname component names an 14619370Spst * existing file that is neither a directory nor a symbolic 14719370Spst * link to a directory." 14819370Spst */ 14919370Spst ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0); 15019370Spst ATF_REQUIRE(errno == ENOTDIR); 15119370Spst } 15219370Spst} 15319370Spst 15419370SpstATF_TC(access_notexist); 15519370SpstATF_TC_HEAD(access_notexist, tc) 15619370Spst{ 15719370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT"); 15819370Spst} 15919370Spst 16019370SpstATF_TC_BODY(access_notexist, tc) 16119370Spst{ 16219370Spst size_t i; 16319370Spst 16419370Spst for (i = 0; i < __arraycount(mode); i++) { 16519370Spst 16619370Spst errno = 0; 16719370Spst 16819370Spst ATF_REQUIRE(access("", mode[i]) != 0); 16919370Spst ATF_REQUIRE(errno == ENOENT); 17019370Spst } 17119370Spst} 17219370Spst 17319370SpstATF_TC(access_toolong); 17419370SpstATF_TC_HEAD(access_toolong, tc) 17519370Spst{ 17619370Spst atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG"); 17719370Spst} 17819370Spst 17919370SpstATF_TC_BODY(access_toolong, tc) 18019370Spst{ 18119370Spst char *buf; 18219370Spst size_t i; 18319370Spst 18419370Spst buf = malloc(PATH_MAX); 18519370Spst 18619370Spst if (buf == NULL) 18719370Spst return; 18819370Spst 18919370Spst for (i = 0; i < PATH_MAX; i++) 19019370Spst buf[i] = 'x'; 19119370Spst 19219370Spst for (i = 0; i < __arraycount(mode); i++) { 19319370Spst 19419370Spst errno = 0; 19519370Spst 19619370Spst ATF_REQUIRE(access(buf, mode[i]) != 0); 19719370Spst ATF_REQUIRE(errno == ENAMETOOLONG); 19819370Spst } 199 200 free(buf); 201} 202 203ATF_TP_ADD_TCS(tp) 204{ 205 206 ATF_TP_ADD_TC(tp, access_access); 207 ATF_TP_ADD_TC(tp, access_fault); 208 ATF_TP_ADD_TC(tp, access_inval); 209 ATF_TP_ADD_TC(tp, access_notdir); 210 ATF_TP_ADD_TC(tp, access_notexist); 211 ATF_TP_ADD_TC(tp, access_toolong); 212 213 return atf_no_error(); 214} 215