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@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
main(int ac,char ** av)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
sigsegv_handler(int sig)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
setup(void)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
cleanup(void)139 static void cleanup(void)
140 {
141 tst_rmdir();
142 }
143