fix memset
[heimdal.git] / lib / roken / dirent-test.c
blob2ac3827fb12f38c1ab47ccb414bc738448063178
1 /***********************************************************************
2 * Copyright (c) 2009, Secure Endpoints Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 **********************************************************************/
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <direct.h>
36 #include <errno.h>
37 #include <io.h>
38 #include <fcntl.h>
39 #include <sys/stat.h>
40 #include <string.h>
41 #include "dirent.h"
43 /* Note that we create a known directory structure in a subdirectory
44 of the current directory to run our tests. */
46 #define TESTDIR "dirent-test-dir"
48 const char * dir_entries[] = {
49 "A",
50 "B",
51 "C",
52 "CAA",
53 "CAAA",
54 "CABBBB",
55 "CAABBB.txt",
56 "A filename with spaces"
59 const char * entries_begin_with_C[] = {
60 "C",
61 "CAA",
62 "CAAA",
63 "CABBBB",
64 "CAABBB.txt"
67 const char * entries_end_with_A[] = {
68 "A",
69 "CAA",
70 "CAAA"
73 const int n_dir_entries = sizeof(dir_entries)/sizeof(dir_entries[0]);
75 int teardown_test(void);
77 void fail_test(const char * reason, ...)
79 va_list args;
81 va_start(args, reason);
82 vfprintf(stderr, reason, args);
83 va_end(args);
85 fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno));
86 teardown_test();
87 abort();
90 void fail_test_nf(const char * format, ...)
92 va_list args;
94 fprintf(stderr, "FAIL:");
96 va_start(args, format);
97 vfprintf(stderr, format, args);
98 va_end(args);
100 fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno));
103 int touch(const char * filename)
105 int fd;
107 fd = _open(filename, _O_CREAT, _S_IREAD| _S_IWRITE);
109 if (fd == -1)
110 return -1;
112 return _close(fd);
115 int setup_test(void)
117 int i;
119 fprintf(stderr, "Creating test directory %s ...\n", TESTDIR);
121 if (_mkdir(TESTDIR))
122 fail_test("Can't create test directory \"" TESTDIR "\"");
124 if (_chdir(TESTDIR))
125 fail_test("Can't change to test directory");
127 for (i=0; i < n_dir_entries; i++) {
128 if (touch(dir_entries[i]))
129 fail_test("Can't create test file '%s'", dir_entries[i]);
132 fprintf(stderr, "Done with test setup.\n");
134 return 0;
137 int teardown_test(void)
139 char dirname[_MAX_PATH];
140 size_t len;
141 int i;
143 printf ("Begin cleanup...\n");
145 if (_getcwd(dirname, sizeof(dirname)/sizeof(char)) != NULL &&
147 (len = strlen(dirname)) > sizeof(TESTDIR)/sizeof(char) &&
149 !strcmp(dirname + len + 1 - sizeof(TESTDIR)/sizeof(char), TESTDIR)) {
151 /* fallthrough */
153 } else {
154 /* did we create the directory? */
156 if (!_rmdir( TESTDIR )) {
157 fprintf(stderr, "Removed test directory\n");
158 return 0;
159 } else {
160 if (errno == ENOTEMPTY) {
161 if (_chdir(TESTDIR)) {
162 fprintf(stderr, "Can't change to test directory. Aborting cleanup.\n");
163 return -1;
164 } else {
165 /* fallthrough */
167 } else {
168 return -1;
173 fprintf(stderr, "Cleaning up test directory %s ...\n", TESTDIR);
175 for (i=0; i < n_dir_entries; i++) {
176 if (_unlink(dir_entries[i])) {
177 /* if the test setup failed, we expect this to happen for
178 at least some files */
182 if (_chdir("..")) {
183 fprintf(stderr, "Can't escape test directory. Giving in.\n");
184 return -1;
187 if (_rmdir( TESTDIR )) {
188 fprintf(stderr, "Can't remove test directory.\n");
189 return -1;
192 printf("Cleaned up test directory\n");
193 return 0;
196 int check_list(const char * filespec, const char ** list, int n, int expect_dot_and_dotdot)
198 DIR * d;
199 struct dirent * e;
200 int n_found = 0;
201 int i;
202 int rv = 0;
203 int retry = 1;
205 d = opendir(filespec);
206 if (d == NULL) {
207 fail_test_nf("opendir failed for [%s]", filespec);
208 return -1;
211 printf("Checking filespec [%s]... ", filespec);
213 retry:
214 while ((e = readdir(d)) != NULL) {
215 n_found ++;
217 if (expect_dot_and_dotdot &&
218 (!strcmp(e->d_name, ".") ||
219 !strcmp(e->d_name, "..")))
220 continue;
222 for (i=0; i < n; i++) {
223 if (!strcmp(list[i], e->d_name))
224 break;
227 if (i == n) {
228 fail_test_nf("Found unexpected entry [%s]", e->d_name);
229 rv = -1;
233 if (n_found != n) {
234 fail_test_nf("Unexpected number of entries [%d]. Expected %d", n_found, n);
235 rv = -1;
238 if (retry) {
239 retry = 0;
240 n_found = 0;
242 rewinddir(d);
243 goto retry;
246 if (closedir(d)) {
247 fail_test_nf("closedir() failed");
250 printf("done\n");
252 return rv;
255 int run_tests()
257 /* assumes that the test directory has been set up and we have
258 changed into the test directory. */
260 check_list("*", dir_entries, n_dir_entries + 2, 1);
261 check_list("*.*", dir_entries, n_dir_entries + 2, 1);
262 check_list("C*", entries_begin_with_C, sizeof(entries_begin_with_C)/sizeof(entries_begin_with_C[0]), 0);
263 check_list("*A", entries_end_with_A, sizeof(entries_end_with_A)/sizeof(entries_end_with_A[0]), 0);
265 return 0;
268 int main(int argc, char ** argv)
270 if (setup_test())
271 return 1;
273 run_tests();
275 teardown_test();
277 return 0;