blob: 99ad6bb029e0edfdbea6b0ecb2b3456c4e2f655d [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
Cyril Hrubiscaf3d342013-03-18 14:10:32 +01002 * Copyright (c) International Business Machines Corp., 2001
Cyril Hrubis85f662d2013-03-18 19:22:39 +01003 * written by Wayne Boyer
4 * Copyright (c) 2013 Markos Chandras
5 * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
plars865695b2001-08-27 22:15:12 +00006 *
Cyril Hrubiscaf3d342013-03-18 14:10:32 +01007 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
plars865695b2001-08-27 22:15:12 +000011 *
Cyril Hrubiscaf3d342013-03-18 14:10:32 +010012 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU General Public License for more details.
plars865695b2001-08-27 22:15:12 +000016 *
Cyril Hrubiscaf3d342013-03-18 14:10:32 +010017 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000020 */
21
Cyril Hrubis85f662d2013-03-18 19:22:39 +010022#include <stdio.h>
23#include <errno.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
plars865695b2001-08-27 22:15:12 +000027
plars865695b2001-08-27 22:15:12 +000028#include "test.h"
Cyril Hrubisc0235352013-04-15 19:42:31 +020029#include "safe_macros.h"
Cyril Hrubis85f662d2013-03-18 19:22:39 +010030#include "getdents.h"
plars865695b2001-08-27 22:15:12 +000031
Cyril Hrubiscaf3d342013-03-18 14:10:32 +010032static void cleanup(void);
33static void setup(void);
plars865695b2001-08-27 22:15:12 +000034
Cyril Hrubisc0235352013-04-15 19:42:31 +020035static void reset_flags(void);
36static void check_flags(void);
37static void set_flag(const char *name);
38
plars865695b2001-08-27 22:15:12 +000039char *TCID = "getdents01";
40int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000041
Markos Chandras28894f52013-03-18 10:54:53 +000042static int longsyscall;
43
Cyril Hrubiscaf3d342013-03-18 14:10:32 +010044static option_t options[] = {
45 /* -l long option. Tests getdents64 */
46 {"l", &longsyscall, NULL},
Markos Chandras28894f52013-03-18 10:54:53 +000047 {NULL, NULL, NULL}
48};
49
Cyril Hrubiscaf3d342013-03-18 14:10:32 +010050static void help(void)
Markos Chandras28894f52013-03-18 10:54:53 +000051{
52 printf(" -l Test the getdents64 system call\n");
53}
54
Cyril Hrubisc0235352013-04-15 19:42:31 +020055enum entry_type {
56 ENTRY_DIR,
57 ENTRY_FILE,
58 ENTRY_SYMLINK,
59};
60
61struct testcase {
62 const char *name;
63 enum entry_type type;
64 int create:1;
65 int found:1;
66};
67
68struct testcase testcases[] = {
69 {.name = ".", .create = 0, .type = ENTRY_DIR},
70 {.name = "..", .create = 0, .type = ENTRY_DIR},
71 {.name = "dir", .create = 1, .type = ENTRY_DIR},
72 {.name = "file", .create = 1, .type = ENTRY_FILE},
73 {.name = "symlink", .create = 1, .type = ENTRY_SYMLINK},
74};
75
76/*
77 * Big enough for dirp entires + data, the current size returned
78 * by kernel is 128 bytes.
79 */
Cyril Hrubis85f662d2013-03-18 19:22:39 +010080#define BUFSIZE 512
81
plars74948ad2002-11-14 16:16:14 +000082int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000083{
Garrett Cooper2cb52912011-03-04 01:21:59 -080084 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020085 const char *msg;
plars865695b2001-08-27 22:15:12 +000086 int rval, fd;
Cyril Hrubis85f662d2013-03-18 19:22:39 +010087 struct linux_dirent64 *dirp64;
88 struct linux_dirent *dirp;
89 void *buf;
90
91 /* The buffer is allocated to make sure it's suitably aligned */
92 buf = malloc(BUFSIZE);
93
94 if (buf == NULL)
95 tst_brkm(TBROK, NULL, "malloc failed");
96
97 dirp64 = buf;
98 dirp = buf;
plars865695b2001-08-27 22:15:12 +000099
Cyril Hrubiscaf3d342013-03-18 14:10:32 +0100100 if ((msg = parse_opts(ac, av, options, &help)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800101 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000102
Garrett Cooper2cb52912011-03-04 01:21:59 -0800103 setup();
plars865695b2001-08-27 22:15:12 +0000104
plars865695b2001-08-27 22:15:12 +0000105 for (lc = 0; TEST_LOOPING(lc); lc++) {
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100106 const char *d_name;
107
Caspar Zhangd59a6592013-03-07 14:59:12 +0800108 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000109
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100110 if ((fd = open(".", O_RDONLY)) == -1)
plars865695b2001-08-27 22:15:12 +0000111 tst_brkm(TBROK, cleanup, "open of directory failed");
robbiew6eaecb22005-12-22 20:18:22 +0000112
Markos Chandras28894f52013-03-18 10:54:53 +0000113 if (longsyscall)
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100114 rval = getdents64(fd, dirp64, BUFSIZE);
Markos Chandras28894f52013-03-18 10:54:53 +0000115 else
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100116 rval = getdents(fd, dirp, BUFSIZE);
Markos Chandras28894f52013-03-18 10:54:53 +0000117
Garrett Cooper2cb52912011-03-04 01:21:59 -0800118 if (rval < 0) {
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100119 if (errno == ENOSYS)
120 tst_resm(TCONF, "syscall not implemented");
121 else
122 tst_resm(TFAIL | TERRNO,
123 "getdents failed unexpectedly");
plars865695b2001-08-27 22:15:12 +0000124 continue;
125 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000126
Garrett Cooper2cb52912011-03-04 01:21:59 -0800127 if (rval == 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800128 tst_resm(TFAIL,
129 "getdents failed - returned end of directory");
plars865695b2001-08-27 22:15:12 +0000130 continue;
131 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000132
Cyril Hrubisc0235352013-04-15 19:42:31 +0200133 reset_flags();
plars865695b2001-08-27 22:15:12 +0000134
Cyril Hrubisc0235352013-04-15 19:42:31 +0200135 do {
136 size_t d_reclen;
137
138 if (longsyscall) {
139 d_reclen = dirp64->d_reclen;
140 d_name = dirp64->d_name;
141 } else {
142 d_reclen = dirp->d_reclen;
143 d_name = dirp->d_name;
144 }
145
146 set_flag(d_name);
147
148 tst_resm(TINFO, "Found '%s'", d_name);
149
150 rval -= d_reclen;
151
152 if (longsyscall)
153 dirp64 = (void*)dirp64 + d_reclen;
154 else
155 dirp = (void*)dirp + d_reclen;
156
157 } while (rval > 0);
plars865695b2001-08-27 22:15:12 +0000158
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100159 if (close(fd) == -1)
Cyril Hrubisc0235352013-04-15 19:42:31 +0200160 tst_brkm(TBROK | TERRNO, cleanup, "Directory close failed");
161
162 check_flags();
plars865695b2001-08-27 22:15:12 +0000163 }
164
Cyril Hrubis85f662d2013-03-18 19:22:39 +0100165 free(buf);
166
plars865695b2001-08-27 22:15:12 +0000167 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800168 tst_exit();
plars865695b2001-08-27 22:15:12 +0000169}
170
Cyril Hrubisc0235352013-04-15 19:42:31 +0200171static void reset_flags(void)
172{
173 int i;
174
175 for (i = 0; i < ARRAY_SIZE(testcases); i++)
176 testcases[i].found = 0;
177}
178
179static void check_flags(void)
180{
181 int i, err = 0;
182
183 for (i = 0; i < ARRAY_SIZE(testcases); i++) {
184 if (!testcases[i].found) {
185 tst_resm(TINFO, "Entry '%s' not found", testcases[i].name);
186 err++;
187 }
188 }
189
190 if (err)
191 tst_resm(TFAIL, "Some entires not found");
192 else
193 tst_resm(TPASS, "All entires found");
194}
195
196static void set_flag(const char *name)
197{
198 int i;
199
200 for (i = 0; i < ARRAY_SIZE(testcases); i++) {
201 if (!strcmp(name, testcases[i].name)) {
202 testcases[i].found = 1;
203 return;
204 }
205 }
206
207 tst_resm(TFAIL, "Unexpected entry '%s' found", name);
208}
209
Cyril Hrubiscaf3d342013-03-18 14:10:32 +0100210static void setup(void)
plars865695b2001-08-27 22:15:12 +0000211{
Cyril Hrubisc0235352013-04-15 19:42:31 +0200212 int i;
213
plars865695b2001-08-27 22:15:12 +0000214 tst_sig(NOFORK, DEF_HANDLER, cleanup);
215
plars865695b2001-08-27 22:15:12 +0000216 tst_tmpdir();
Garrett Cooper2cb52912011-03-04 01:21:59 -0800217
Cyril Hrubisc0235352013-04-15 19:42:31 +0200218 for (i = 0; i < ARRAY_SIZE(testcases); i++) {
219
220 if (!testcases[i].create)
221 continue;
222
223 switch (testcases[i].type) {
224 case ENTRY_DIR:
225 SAFE_MKDIR(cleanup, testcases[i].name, 0777);
226 break;
227 case ENTRY_FILE:
228 SAFE_FILE_PRINTF(cleanup, testcases[i].name, " ");
229 break;
230 case ENTRY_SYMLINK:
231 SAFE_SYMLINK(cleanup, "nonexistent", testcases[i].name);
232 break;
233 }
234 }
235
Garrett Cooper2cb52912011-03-04 01:21:59 -0800236 TEST_PAUSE;
plars865695b2001-08-27 22:15:12 +0000237}
238
Cyril Hrubiscaf3d342013-03-18 14:10:32 +0100239static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000240{
Garrett Cooper2cb52912011-03-04 01:21:59 -0800241 tst_rmdir();
242}