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