Home | History | Annotate | Download | only in readdir
      1 /*
      2  * Copyright (C) Bull S.A. 2001
      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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * DESCRIPTION
     22  *      Try to readdir with Invalid directory stream descriptor dir.
     23  *
     24  * ALGORITHM
     25  *      loop if that option was specified
     26  *      call readdir() with an invalid file descriptor
     27  *      check the errno value
     28  *        issue a PASS message if we get EBADF - errno 9
     29  *      otherwise, the tests fails
     30  *        issue a FAIL message
     31  *        call cleanup
     32  *
     33  * NOTE
     34  *	The POSIX standard says:
     35  *	  The readdir() function may fail if:
     36  *	  [EBADF] The dirp argument does not refer to an open directory stream.
     37  *	  (Note that readdir() is not _required_ to fail in this case.)
     38  *
     39  * HISTORY
     40  *      04/2002 - Written by Jacky Malcles
     41  *
     42  *      06/2003 - Added code to catch SIGSEGV and return TCONF.
     43  *		Robbie Williamson<robbiew (at) us.ibm.com>
     44  */
     45 
     46 #include <sys/types.h>
     47 #include <sys/stat.h>
     48 #include <fcntl.h>
     49 #include <dirent.h>
     50 #include <unistd.h>
     51 #include <errno.h>
     52 #include <string.h>
     53 #include <signal.h>
     54 
     55 #include "test.h"
     56 
     57 static void setup(void);
     58 static void cleanup(void);
     59 
     60 char *TCID = "readdir02";
     61 int TST_TOTAL = 1;
     62 
     63 int main(int ac, char **av)
     64 {
     65 	int lc;
     66 	DIR *test_dir;
     67 	struct dirent *dptr;
     68 
     69 	tst_parse_opts(ac, av, NULL, NULL);
     70 
     71 	setup();
     72 
     73 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     74 
     75 		tst_count = 0;
     76 
     77 		if ((test_dir = opendir(".")) == NULL) {
     78 			tst_resm(TFAIL, "opendir(\".\") Failed, errno=%d : %s",
     79 				 errno, strerror(errno));
     80 		} else {
     81 			if (closedir(test_dir) < 0) {
     82 				tst_resm(TFAIL,
     83 					 "closedir(\".\") Failed, errno=%d : %s",
     84 					 errno, strerror(errno));
     85 			} else {
     86 				dptr = readdir(test_dir);
     87 				switch (errno) {
     88 				case EBADF:
     89 					tst_resm(TPASS,
     90 						 "expected failure - errno = %d : %s",
     91 						 errno, strerror(errno));
     92 					break;
     93 				default:
     94 					if (dptr != NULL) {
     95 						tst_brkm(TFAIL, cleanup,
     96 							 "call failed with an "
     97 							 "unexpected error - %d : %s",
     98 							 errno,
     99 							 strerror(errno));
    100 					} else {
    101 						tst_resm(TINFO,
    102 							 "readdir() is not _required_ to fail, "
    103 							 "errno = %d  ", errno);
    104 					}
    105 				}
    106 			}
    107 
    108 		}
    109 
    110 	}
    111 
    112 	cleanup();
    113 	tst_exit();
    114 }
    115 
    116 static void sigsegv_handler(int sig)
    117 {
    118 	tst_resm(TCONF,
    119 		 "This system's implementation of closedir() will not allow this test to execute properly.");
    120 	cleanup();
    121 }
    122 
    123 static void setup(void)
    124 {
    125 	struct sigaction act;
    126 
    127 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    128 
    129 	act.sa_handler = sigsegv_handler;
    130 	act.sa_flags = 0;
    131 	sigemptyset(&act.sa_mask);
    132 	sigaction(SIGSEGV, &act, NULL);
    133 
    134 	TEST_PAUSE;
    135 
    136 	tst_tmpdir();
    137 }
    138 
    139 static void cleanup(void)
    140 {
    141 	tst_rmdir();
    142 }
    143