1/* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31 * 32 */ 33/* $Id: stat06.c,v 1.10 2009/11/02 13:57:19 subrata_modak Exp $ */ 34/********************************************************** 35 * 36 * OS Test - Silicon Graphics, Inc. 37 * 38 * TEST IDENTIFIER : stat06 39 * 40 * EXECUTED BY : anyone 41 * 42 * TEST TITLE : stat(2) negative path testcases 43 * 44 * PARENT DOCUMENT : None 45 * 46 * TEST CASE TOTAL : 7 47 * 48 * WALL CLOCK TIME : 1 49 * 50 * CPU TYPES : ALL 51 * 52 * AUTHOR : Richard Logan 53 * 54 * CO-PILOT : William Roske 55 * 56 * DATE STARTED : 03/30/94 57 * 58 * INITIAL RELEASE : UNICOS 7.0 59 * 60 * TEST CASES 61 * 62 * 1-7) See Testcases structure below. 63 * 64 * INPUT SPECIFICATIONS 65 * The standard options for system call tests are accepted. 66 * (See the parse_opts(3) man page). 67 * -h : print help and exit 68 * 69 * OUTPUT SPECIFICATIONS 70 *$ 71 * DURATION 72 * Terminates - with frequency and infinite modes. 73 * 74 * SIGNALS 75 * Uses SIGUSR1 to pause before test if option set. 76 * (See the parse_opts(3) man page). 77 * 78 * RESOURCES 79 * None 80 * 81 * ENVIRONMENTAL NEEDS 82 * The libcuts.a and libsys.a libraries must be included in 83 * the compilation of this test. 84 * 85 * SPECIAL PROCEDURAL REQUIREMENTS 86 * None 87 * 88 * INTERCASE DEPENDENCIES 89 * None 90 * 91 * DETAILED DESCRIPTION 92 * This is a Phase I test for the stat(2) system call. It is intended 93 * to provide a limited exposure of the system call, for now. It 94 * should/will be extended when full functional tests are written for 95 * stat(2). 96 * 97 * Setup: 98 * Setup signal handling. 99 * Pause for SIGUSR1 if option specified. 100 * 101 * Test: 102 * Loop if the proper options are given. 103 * Execute system call 104 * Check return code, if system call failed (return=-1) 105 * Log the errno and Issue a FAIL message. 106 * Otherwise, Issue a PASS message. 107 * 108 * Cleanup: 109 * Print errno log and/or timing stats if options given 110 * 111 * 112 *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/ 113 114#include <sys/types.h> 115#include <fcntl.h> 116#include <sys/stat.h> 117#include <sys/mman.h> 118#include <errno.h> 119#include <string.h> 120#include <signal.h> 121#include <setjmp.h> 122#include <unistd.h> 123#include "test.h" 124 125void setup(); 126void cleanup(); 127 128char *TCID = "stat06"; 129 130char *bad_addr = 0; 131 132#if !defined(UCLINUX) 133int high_address_setup(); 134char High_address[64]; 135#endif 136int longpath_setup(); 137int no_setup(); 138int filepath_setup(); 139char Longpathname[PATH_MAX + 2]; 140struct stat statbuf; 141jmp_buf sig11_recover; 142void sig11_handler(int sig); 143 144struct test_case_t { 145 char *pathname; 146 struct stat *stbuf; 147 char *desc; 148 int exp_errno; 149 int (*setupfunc) (); 150} Test_cases[] = { 151 { 152 "nonexistfile", &statbuf, "non-existent file", ENOENT, no_setup}, { 153 "", &statbuf, "path is empty string", ENOENT, no_setup}, { 154 "nefile/file", &statbuf, "path contains a non-existent file", 155 ENOENT, no_setup}, { 156 "file/file", &statbuf, "path contains a regular file", 157 ENOTDIR, filepath_setup}, { 158 Longpathname, &statbuf, "pathname too long", ENAMETOOLONG, 159 longpath_setup}, 160#if !defined(UCLINUX) 161 { 162 High_address, &statbuf, "address beyond address space", EFAULT, 163 high_address_setup}, { 164 (char *)-1, &statbuf, "negative address", EFAULT, no_setup}, 165#endif 166 { 167 NULL, NULL, NULL, 0, no_setup} 168}; 169 170int TST_TOTAL = ARRAY_SIZE(Test_cases); 171 172/*********************************************************************** 173 * Main 174 ***********************************************************************/ 175int main(int ac, char **av) 176{ 177 int lc; 178 char *fname; 179 char *desc; 180 int ind; 181 struct stat *stbuf; 182 struct sigaction sa, osa; 183 184 /*************************************************************** 185 * parse standard options 186 ***************************************************************/ 187 tst_parse_opts(ac, av, NULL, NULL); 188 189 /*************************************************************** 190 * perform global setup for test 191 ***************************************************************/ 192 setup(); 193 194 /*************************************************************** 195 * check looping state if -c option given 196 ***************************************************************/ 197 for (lc = 0; TEST_LOOPING(lc); lc++) { 198 199 tst_count = 0; 200 201 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 202 203 fname = Test_cases[ind].pathname; 204 desc = Test_cases[ind].desc; 205 stbuf = Test_cases[ind].stbuf; 206 207 if (stbuf == (struct stat *)-1) { 208 /* special sig11 case */ 209 sa.sa_handler = &sig11_handler; 210 sigemptyset(&sa.sa_mask); 211 sa.sa_flags = 0; 212 213 sigaction(SIGSEGV, NULL, &osa); 214 sigaction(SIGSEGV, &sa, NULL); 215 216 if (setjmp(sig11_recover)) { 217 TEST_RETURN = -1; 218 TEST_ERRNO = EFAULT; 219 } else { 220 TEST(stat(fname, stbuf)); 221 } 222 sigaction(SIGSEGV, &osa, NULL); 223 } else { 224 /* 225 * Call stat(2) 226 */ 227 228 TEST(stat(fname, stbuf)); 229 } 230 231 /* check return code */ 232 if (TEST_RETURN == -1) { 233 if (TEST_ERRNO == 234 Test_cases[ind].exp_errno) 235 tst_resm(TPASS, 236 "stat(<%s>, &stbuf) Failed, errno=%d", 237 desc, TEST_ERRNO); 238 else 239 tst_resm(TFAIL, 240 "stat(<%s>, &stbuf) Failed, errno=%d, expected errno:%d", 241 desc, TEST_ERRNO, 242 Test_cases 243 [ind].exp_errno); 244 } else { 245 tst_resm(TFAIL, 246 "stat(<%s>, &stbuf) returned %ld, expected -1, errno:%d", 247 desc, TEST_RETURN, 248 Test_cases[ind].exp_errno); 249 } 250 } 251 252 } 253 254 cleanup(); 255 tst_exit(); 256} 257 258/*************************************************************** 259 * setup() - performs all ONE TIME setup for this test. 260 ***************************************************************/ 261void setup(void) 262{ 263 int ind; 264 265 tst_sig(NOFORK, DEF_HANDLER, cleanup); 266 267 TEST_PAUSE; 268 269 tst_tmpdir(); 270 271#if !defined(UCLINUX) 272 bad_addr = mmap(0, 1, PROT_NONE, 273 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0); 274 if (bad_addr == MAP_FAILED) { 275 tst_brkm(TBROK, cleanup, "mmap failed"); 276 } 277 Test_cases[6].pathname = bad_addr; 278#endif 279 280 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 281 Test_cases[ind].setupfunc(); 282 } 283 284} 285 286/*************************************************************** 287 * cleanup() - performs all ONE TIME cleanup for this test at 288 * completion or premature exit. 289 ***************************************************************/ 290void cleanup(void) 291{ 292 293 tst_rmdir(); 294 295} 296 297/****************************************************************** 298 * no_setup() - does nothing 299 ******************************************************************/ 300int no_setup(void) 301{ 302 return 0; 303} 304 305#if !defined(UCLINUX) 306 307/****************************************************************** 308 * high_address_setup() - generates an address that should cause a segfault 309 ******************************************************************/ 310int high_address_setup(void) 311{ 312 int ind; 313 314 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 315 if (Test_cases[ind].pathname == High_address) { 316 /*if (strcmp(Test_cases[ind].pathname, HIGH_ADDRESS) == 0) { ** */ 317 Test_cases[ind].pathname = (char *)(sbrk(0) + 5); 318 break; 319 } 320 } 321 return 0; 322 323} 324#endif 325 326/****************************************************************** 327 * longpath_setup() - creates a filename that is too long 328 ******************************************************************/ 329int longpath_setup(void) 330{ 331 int ind; 332 333 for (ind = 0; ind <= PATH_MAX + 1; ind++) { 334 Longpathname[ind] = 'a'; 335 } 336 return 0; 337 338} 339 340/****************************************************************** 341 * filepath_setup() creates a file the exists that we will treat as a directory 342 ******************************************************************/ 343int filepath_setup(void) 344{ 345 int fd; 346 347 if ((fd = creat("file", 0777)) == -1) { 348 tst_brkm(TBROK, cleanup, "creat(file) failed, errno:%d %s", 349 errno, strerror(errno)); 350 } 351 close(fd); 352 return 0; 353} 354 355/****************************************************************** 356 * sig11_handler() - our segfault recover hack 357 ******************************************************************/ 358void sig11_handler(int sig) 359{ 360 longjmp(sig11_recover, 1); 361} 362