access05.c revision bfc42dad4386b0088e4b5c3bc7fdfc1ad017ac7b
1/* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20/* 21 * Test Name: access05 22 * 23 * Test Description: 24 * Verify that, 25 * 1. access() fails with -1 return value and sets errno to EACCES 26 * if the permission bits of the file mode do not permit the 27 * requested (Read/Write/Execute) access. 28 * 2. access() fails with -1 return value and sets errno to EINVAL 29 * if the specified access mode argument is invalid. 30 * 3. access() fails with -1 return value and sets errno to EFAULT 31 * if the pathname points outside allocate address space for the 32 * process. 33 * 4. access() fails with -1 return value and sets errno to ENOENT 34 * if the specified file doesn't exist (or pathname is NULL). 35 * 5. access() fails with -1 return value and sets errno to ENAMETOOLONG 36 * if the pathname size is > PATH_MAX characters. 37 * 38 * Expected Result: 39 * access() should fail with return value -1 and set expected errno. 40 * 41 * Algorithm: 42 * Setup: 43 * Setup signal handling. 44 * Create temporary directory. 45 * Pause for SIGUSR1 if option specified. 46 * 47 * Test: 48 * Loop if the proper options are given. 49 * Execute system call 50 * Check return code, if system call failed (return=-1) 51 * if errno set == expected errno 52 * Issue sys call fails with expected return value and errno. 53 * Otherwise, 54 * Issue sys call fails with unexpected errno. 55 * Otherwise, 56 * Issue sys call returns unexpected value. 57 * 58 * Cleanup: 59 * Print errno log and/or timing stats if options given 60 * Delete the temporary directory(s)/file(s) created. 61 * 62 * Usage: <for command-line> 63 * access05 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 64 * where, -c n : Run n copies concurrently. 65 * -e : Turn on errno logging. 66 * -i n : Execute test n times. 67 * -I x : Execute test for x seconds. 68 * -P x : Pause for x seconds between iterations. 69 * -t : Turn on syscall timing. 70 * 71 * HISTORY 72 * 07/2001 Ported by Wayne Boyer 73 * 74 * RESTRICTIONS: 75 * This test should be run by 'non-super-user' only. 76 * 77 */ 78 79#include <stdio.h> 80#include <errno.h> 81#include <unistd.h> 82#include <fcntl.h> 83#include <string.h> 84#include <signal.h> 85#include <sys/types.h> 86#include <sys/stat.h> 87 88#include "test.h" 89#include "usctest.h" 90 91#define INV_OK -1 92#define TEST_FILE1 "test_file1" 93#define TEST_FILE2 "test_file2" 94#define TEST_FILE3 "test_file3" 95#define TEST_FILE4 "test_file4" 96 97#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 98 99int no_setup(); 100int setup1(); /* setup() to test access() for EACCES */ 101int setup2(); /* setup() to test access() for EACCES */ 102int setup3(); /* setup() to test access() for EACCES */ 103int setup4(); /* setup() to test access() for EINVAL */ 104int longpath_setup(); /* setup function to test access() for ENAMETOOLONG */ 105 106char Longpathname[PATH_MAX+2]; 107char High_address_node[64]; 108 109struct test_case_t { /* test case structure */ 110 char *pathname; 111 int a_mode; 112 char *desc; 113 int exp_errno; 114 int (*setupfunc)(); 115} Test_cases[] = { 116 { TEST_FILE1, R_OK, "Read Access denied on file", EACCES, setup1 }, 117 { TEST_FILE2, W_OK, "Write Access denied on file", EACCES, setup2 }, 118 { TEST_FILE3, X_OK, "Execute Access denied on file", EACCES, setup3 }, 119 { TEST_FILE4, INV_OK, "Access mode invalid", EINVAL, setup4 }, 120 { High_address_node, R_OK, "Address beyond address space", EFAULT, no_setup }, 121 { (char *)-1, R_OK, "Negative address", EFAULT, no_setup }, 122 { "", W_OK, "Pathname is empty", ENOENT, no_setup }, 123 { Longpathname, R_OK, "Pathname too long", ENAMETOOLONG, longpath_setup }, 124 { NULL, 0, NULL, 0, no_setup } 125}; 126 127char *TCID="access05"; /* Test program identifier. */ 128int TST_TOTAL=8; /* Total number of test cases. */ 129extern int Tst_count; /* Test Case counter for tst_* routines */ 130int exp_enos[]={EACCES, EFAULT, EINVAL, ENOENT, ENAMETOOLONG, 0}; 131 132void setup(); /* Main setup function of test */ 133void cleanup(); /* cleanup function for the test */ 134 135int 136main(int ac, char **av) 137{ 138 int lc; /* loop counter */ 139 char *msg; /* message returned from parse_opts */ 140 char *file_name; /* name of the testfile */ 141 char *test_desc; /* test specific message */ 142 int access_mode; /* specified access mode for testfile */ 143 int ind; /* counter for testcase looping */ 144 145 /* Parse standard options given to run the test. */ 146 msg = parse_opts(ac, av, (option_t *) NULL, NULL); 147 if (msg != (char *) NULL) { 148 tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); 149 } 150 151 /* Perform global setup for test */ 152 setup(); 153 154 /* set the expected errnos... */ 155 TEST_EXP_ENOS(exp_enos); 156 157 /* Check looping state if -i option given */ 158 for (lc = 0; TEST_LOOPING(lc); lc++) { 159 /* Reset Tst_count in case we are looping. */ 160 Tst_count = 0; 161 162 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 163 file_name = Test_cases[ind].pathname; 164 access_mode = Test_cases[ind].a_mode; 165 test_desc = Test_cases[ind].desc; 166 167 if (file_name == High_address_node) { 168 file_name = (char *)get_high_address(); 169 } 170 171 /* 172 * Call access(2) to test different test conditions. 173 * verify that it fails with -1 return value and 174 * sets appropriate errno. 175 */ 176 TEST(access(file_name, access_mode)); 177 178 if (TEST_RETURN != -1) { 179 tst_resm(TFAIL, "access() returned %d, " 180 "expected -1, errno:%d", TEST_RETURN, 181 Test_cases[ind].exp_errno); 182 continue; 183 } 184 185 TEST_ERROR_LOG(TEST_ERRNO); 186 187 /* 188 * Call a function to verify whether 189 * the specified file has specified 190 * access mode. 191 */ 192 if (TEST_ERRNO == Test_cases[ind].exp_errno) { 193 tst_resm(TPASS, "access() fails, %s, errno:%d", 194 test_desc, TEST_ERRNO); 195 } else { 196 tst_resm(TFAIL, "access() fails, %s, errno:%d, " 197 "expected errno:%d", test_desc, 198 TEST_ERRNO, Test_cases[ind].exp_errno); 199 } 200 } /* Test Case Looping */ 201 } /* End for TEST_LOOPING */ 202 203 /* Call cleanup() to undo setup done for the test. */ 204 cleanup(); 205 206 /*NOTREACHED*/ 207} 208 209/* 210 * setup() - performs all ONE TIME setup for this test. 211 * 212 * Create a temporary directory and change directory to it. 213 * Call individual test specific setup functions. 214 */ 215void 216setup() 217{ 218 int ind; /* counter for testsetup functions */ 219 220 /* capture signals */ 221 tst_sig(NOFORK, DEF_HANDLER, cleanup); 222 223 /* Check that the test process id is not root/super-user */ 224 if (geteuid() == 0) { 225 tst_brkm(TBROK, NULL, "Must be non-root/super for this test!"); 226 tst_exit(); 227 } 228 229 /* Pause if that option was specified */ 230 TEST_PAUSE; 231 232 /* make a temp directory and cd to it */ 233 tst_tmpdir(); 234 235 /* call individual setup functions */ 236 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 237 Test_cases[ind].setupfunc(); 238 } 239} 240 241/* 242 * no_setup() - some test conditions do not need any setup. 243 * Hence, this function simply returns 0. 244 */ 245int 246no_setup() 247{ 248 return 0; 249} 250 251/* 252 * setup1() - Setup function to test access() for return value -1 253 * and errno EACCES when read access denied for specified 254 * testfile. 255 * 256 * Creat/open a testfile and close it. 257 * Deny read access permissions on testfile. 258 * This function returns 0. 259 */ 260int 261setup1() 262{ 263 int fd1; /* file handle for testfile */ 264 265 /* Creat a test file under above directory created */ 266 if ((fd1 = open(TEST_FILE1, O_RDWR|O_CREAT, FILE_MODE)) == -1) { 267 tst_brkm(TBROK, cleanup, 268 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 269 TEST_FILE1, FILE_MODE, errno, strerror(errno)); 270 } 271 272 /* Close the testfile created above */ 273 if (close(fd1) == -1) { 274 tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s", 275 TEST_FILE1, errno, strerror(errno)); 276 } 277 278 /* Change mode permissions on testfile */ 279 if (chmod(TEST_FILE1, 0333) < 0) { 280 tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d", 281 TEST_FILE1, errno); 282 } 283 284 return 0; 285} 286 287/* 288 * setup2() - Setup function to test access() for return value -1 and 289 * errno EACCES when write access denied on testfile. 290 * 291 * Creat/open a testfile and close it. 292 * Deny write access permissions on testfile. 293 * This function returns 0. 294 */ 295int 296setup2() 297{ 298 int fd2; /* file handle for testfile */ 299 300 /* Creat a test file under above directory created */ 301 if ((fd2 = open(TEST_FILE2, O_RDWR|O_CREAT, FILE_MODE)) == -1) { 302 tst_brkm(TBROK, cleanup, 303 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 304 TEST_FILE2, FILE_MODE, errno, strerror(errno)); 305 } 306 307 /* Close the testfile created above */ 308 if (close(fd2) == -1) { 309 tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s", 310 TEST_FILE2, errno, strerror(errno)); 311 } 312 313 /* Change mode permissions on testfile */ 314 if (chmod(TEST_FILE2, 0555) < 0) { 315 tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d", 316 TEST_FILE2, errno); 317 } 318 319 return 0; 320} 321 322/* 323 * setup3() - Setup function to test access() for return value -1 and 324 * errno EACCES when execute access denied on testfile. 325 * 326 * Creat/open a testfile and close it. 327 * Deny search access permissions on testfile. 328 * This function returns 0. 329 */ 330int 331setup3() 332{ 333 int fd3; /* file handle for testfile */ 334 335 /* Creat a test file under above directory created */ 336 if ((fd3 = open(TEST_FILE3, O_RDWR|O_CREAT, FILE_MODE)) == -1) { 337 tst_brkm(TBROK, cleanup, 338 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 339 TEST_FILE3, FILE_MODE, errno, strerror(errno)); 340 } 341 342 /* Close the testfile created above */ 343 if (close(fd3) == -1) { 344 tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s", 345 TEST_FILE3, errno, strerror(errno)); 346 } 347 348 /* Change mode permissions on testfile */ 349 if (chmod(TEST_FILE3, 0666) < 0) { 350 tst_brkm(TBROK, cleanup, "chmod() failed on %s, errno=%d", 351 TEST_FILE3, errno); 352 } 353 354 return 0; 355} 356 357/* 358 * setup4() - Setup function to test access() for return value -1 359 * and errno EINVAL when specified access mode argument is 360 * invalid. 361 * 362 * Creat/open a testfile and close it. 363 * This function returns 0. 364 */ 365int 366setup4() 367{ 368 int fd4; /* file handle for testfile */ 369 370 /* Creat a test file under above directory created */ 371 if ((fd4 = open(TEST_FILE4, O_RDWR|O_CREAT, FILE_MODE)) == -1) { 372 tst_brkm(TBROK, cleanup, 373 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 374 TEST_FILE4, FILE_MODE, errno, strerror(errno)); 375 } 376 377 /* Close the testfile created above */ 378 if (close(fd4) == -1) { 379 tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s", 380 TEST_FILE4, errno, strerror(errno)); 381 } 382 383 return 0; 384} 385 386/* 387 * longpath_setup() - setup to create a node with a name length exceeding 388 * the MAX. length of PATH_MAX. 389 */ 390int 391longpath_setup() 392{ 393 int ind; 394 395 for (ind = 0; ind <= (PATH_MAX + 1); ind++) { 396 Longpathname[ind] = 'a'; 397 } 398 399 return 0; 400} 401 402/* 403 * cleanup() - performs all ONE TIME cleanup for this test at 404 * completion or premature exit. 405 * 406 * Remove the test directory and testfile created in the setup. 407 */ 408void 409cleanup() 410{ 411 /* 412 * print timing stats if that option was specified. 413 * print errno log if that option was specified. 414 */ 415 TEST_CLEANUP; 416 417 /* 418 * Delete the test directory/file and temporary directory 419 * created in the setup. 420 */ 421 tst_rmdir(); 422 423 /* exit with return code appropriate for results */ 424 tst_exit(); 425} 426