blob: 6a824679ab08593358f41efde838015abeed95ca [file] [log] [blame]
Miklos Szeredi3b206c72005-05-06 10:15:26 +00001#include <stdio.h>
2#include <stdarg.h>
3#include <string.h>
4#include <unistd.h>
5#include <fcntl.h>
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +00006#include <dirent.h>
Miklos Szeredi3b206c72005-05-06 10:15:26 +00007#include <errno.h>
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +00008#include <assert.h>
Miklos Szeredi3b206c72005-05-06 10:15:26 +00009#include <sys/types.h>
10#include <sys/stat.h>
11
12
13static char testfile[1024];
14static char testfile2[1024];
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000015static char testdir[1024];
16static char testdir2[1024];
Miklos Szeredi3b206c72005-05-06 10:15:26 +000017static char testname[256];
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000018static char testdata[] = "abcdefghijklmnopqrstuvwxyz";
Miklos Szeredi02709512005-08-03 14:14:47 +000019static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000020static const char *testdir_files[] = { "f1", "f2", NULL};
Miklos Szeredi3b206c72005-05-06 10:15:26 +000021static char zerodata[4096];
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000022static int testdatalen = sizeof(testdata) - 1;
Miklos Szeredi02709512005-08-03 14:14:47 +000023static int testdata2len = sizeof(testdata2) - 1;
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000024
25#define MAX_ENTRIES 1024
Miklos Szeredi3b206c72005-05-06 10:15:26 +000026
27static void test_perror(const char *func, const char *msg)
28{
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000029 fprintf(stderr, "[%s] %s() - %s: %s\n", testname, func, msg,
30 strerror(errno));
Miklos Szeredi3b206c72005-05-06 10:15:26 +000031}
32
33static void test_error(const char *func, const char *msg, ...)
34 __attribute__ ((format (printf, 2, 3)));
35
36static void start_test(const char *fmt, ...)
37 __attribute__ ((format (printf, 1, 2)));
Miklos Szeredi9b813af2005-07-21 07:59:37 +000038
Miklos Szeredi3b206c72005-05-06 10:15:26 +000039static void test_error(const char *func, const char *msg, ...)
40{
41 va_list ap;
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000042 fprintf(stderr, "[%s] %s() - ", testname, func);
Miklos Szeredi3b206c72005-05-06 10:15:26 +000043 va_start(ap, msg);
44 vfprintf(stderr, msg, ap);
45 va_end(ap);
46 fprintf(stderr, "\n");
47}
48
49static void success(void)
50{
51 fprintf(stderr, "[%s] OK\n", testname);
52}
53
54static void start_test(const char *fmt, ...)
55{
56 va_list ap;
57 va_start(ap, fmt);
58 vsprintf(testname, fmt, ap);
59 va_end(ap);
60}
61
62#define PERROR(msg) test_perror(__FUNCTION__, msg)
63#define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
64
65static int check_size(const char *path, int len)
66{
67 struct stat stbuf;
68 int res = stat(path, &stbuf);
69 if (res == -1) {
70 PERROR("stat");
71 return -1;
72 }
73 if (stbuf.st_size != len) {
74 ERROR("length %u instead of %u", (int) stbuf.st_size, (int) len);
75 return -1;
76 }
77 return 0;
78}
79
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +000080static int check_type(const char *path, mode_t type)
81{
82 struct stat stbuf;
83 int res = lstat(path, &stbuf);
84 if (res == -1) {
85 PERROR("lstat");
86 return -1;
87 }
88 if ((stbuf.st_mode & S_IFMT) != type) {
89 ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
90 return -1;
91 }
92 return 0;
93}
94
95static int check_mode(const char *path, mode_t mode)
96{
97 struct stat stbuf;
98 int res = lstat(path, &stbuf);
99 if (res == -1) {
100 PERROR("lstat");
101 return -1;
102 }
103 if ((stbuf.st_mode & 07777) != mode) {
104 ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
105 return -1;
106 }
107 return 0;
108}
109
110static int check_nlink(const char *path, nlink_t nlink)
111{
112 struct stat stbuf;
113 int res = lstat(path, &stbuf);
114 if (res == -1) {
115 PERROR("lstat");
116 return -1;
117 }
118 if (stbuf.st_nlink != nlink) {
119 ERROR("nlink %i instead of %i", stbuf.st_nlink, nlink);
120 return -1;
121 }
122 return 0;
123}
124
125static int check_nonexist(const char *path)
126{
127 struct stat stbuf;
128 int res = lstat(path, &stbuf);
129 if (res == 0) {
130 ERROR("file should not exist");
131 return -1;
132 }
133 if (errno != ENOENT) {
134 ERROR("file should not exist: %s", strerror(errno));
135 return -1;
136 }
137 return 0;
138}
139
Miklos Szeredi02709512005-08-03 14:14:47 +0000140static int check_buffer(const char *buf, const char *data, unsigned len)
141{
142 if (memcmp(buf, data, len) != 0) {
143 ERROR("data mismatch");
144 return -1;
145 }
146 return 0;
147}
148
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000149static int check_data(const char *path, const char *data, int offset,
150 unsigned len)
151{
152 char buf[4096];
153 int res;
154 int fd = open(path, O_RDONLY);
155 if (fd == -1) {
156 PERROR("open");
157 return -1;
158 }
159 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
160 PERROR("lseek");
161 close(fd);
162 return -1;
163 }
164 while (len) {
165 int rdlen = len < sizeof(buf) ? len : sizeof(buf);
166 res = read(fd, buf, rdlen);
167 if (res == -1) {
168 PERROR("read");
169 close(fd);
170 return -1;
171 }
172 if (res != rdlen) {
173 ERROR("short read: %u instead of %u", res, rdlen);
174 close(fd);
175 return -1;
176 }
Miklos Szeredi02709512005-08-03 14:14:47 +0000177 if (check_buffer(buf, data, rdlen) != 0) {
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000178 close(fd);
179 return -1;
180 }
181 data += rdlen;
182 len -= rdlen;
183 }
184 res = close(fd);
185 if (res == -1) {
186 PERROR("close");
187 return -1;
188 }
189 return 0;
190}
191
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000192static int check_dir_contents(const char *path, const char **contents)
193{
194 int i;
195 int res;
Miklos Szeredi02709512005-08-03 14:14:47 +0000196 int err = 0;
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000197 int found[MAX_ENTRIES];
198 const char *cont[MAX_ENTRIES];
199 DIR *dp;
200
201 for (i = 0; contents[i]; i++) {
202 assert(i < MAX_ENTRIES - 3);
203 found[i] = 0;
204 cont[i] = contents[i];
205 }
206 found[i] = 0;
207 cont[i++] = ".";
208 found[i] = 0;
209 cont[i++] = "..";
210 cont[i] = NULL;
211
212 dp = opendir(path);
213 if (dp == NULL) {
214 PERROR("opendir");
215 return -1;
216 }
217 memset(found, 0, sizeof(found));
218 while(1) {
219 struct dirent *de;
220 errno = 0;
221 de = readdir(dp);
222 if (de == NULL) {
223 if (errno) {
224 PERROR("readdir");
225 closedir(dp);
226 return -1;
227 }
228 break;
229 }
230 for (i = 0; cont[i] != NULL; i++) {
231 assert(i < MAX_ENTRIES);
232 if (strcmp(cont[i], de->d_name) == 0) {
233 if (found[i]) {
234 ERROR("duplicate entry <%s>", de->d_name);
235 err--;
236 } else
237 found[i] = 1;
238 break;
239 }
240 }
241 if (!cont[i]) {
242 ERROR("unexpected entry <%s>", de->d_name);
243 err --;
244 }
245 }
246 for (i = 0; cont[i] != NULL; i++) {
247 if (!found[i]) {
248 ERROR("missing entry <%s>", cont[i]);
249 err--;
250 }
251 }
252 res = closedir(dp);
253 if (res == -1) {
254 PERROR("closedir");
255 return -1;
256 }
257 if (err)
258 return -1;
259
260 return 0;
261}
262
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000263static int create_file(const char *path, const char *data, int len)
264{
265 int res;
266 int fd;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000267
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000268 unlink(path);
269 fd = creat(path, 0644);
270 if (fd == -1) {
271 PERROR("creat");
272 return -1;
273 }
274 res = write(fd, data, len);
275 if (res == -1) {
276 PERROR("write");
277 close(fd);
278 return -1;
279 }
280 if (res != len) {
281 ERROR("write is short: %u instead of %u", res, len);
282 close(fd);
283 return -1;
284 }
285 res = close(fd);
286 if (res == -1) {
287 PERROR("close");
288 return -1;
289 }
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000290 res = check_type(path, S_IFREG);
291 if (res == -1)
292 return -1;
293 res = check_mode(path, 0644);
294 if (res == -1)
295 return -1;
296 res = check_nlink(path, 1);
297 if (res == -1)
298 return -1;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000299 res = check_size(path, len);
300 if (res == -1)
301 return -1;
302
303 res = check_data(path, data, 0, len);
304 if (res == -1)
305 return -1;
306
307 return 0;
308}
309
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000310static int cleanup_dir(const char *path, const char **dir_files, int quiet)
311{
312 int i;
313 int err = 0;
314
315 for (i = 0; dir_files[i]; i++) {
316 int res;
317 char fpath[1024];
318 sprintf(fpath, "%s/%s", path, dir_files[i]);
319 res = unlink(fpath);
320 if (res == -1 && !quiet) {
321 PERROR("unlink");
322 err --;
323 }
324 }
325 if (err)
326 return -1;
327
328 return 0;
329}
330
331static int create_dir(const char *path, const char **dir_files)
332{
333 int res;
334 int i;
335
336 rmdir(path);
337 res = mkdir(path, 0755);
338 if (res == -1) {
339 PERROR("mkdir");
340 return -1;
341 }
342 res = check_type(path, S_IFDIR);
343 if (res == -1)
344 return -1;
345 res = check_mode(path, 0755);
346 if (res == -1)
347 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000348
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000349 for (i = 0; dir_files[i]; i++) {
350 char fpath[1024];
351 sprintf(fpath, "%s/%s", path, dir_files[i]);
352 res = create_file(fpath, "", 0);
353 if (res == -1) {
354 cleanup_dir(path, dir_files, 1);
355 return -1;
356 }
357 }
358 res = check_dir_contents(path, dir_files);
359 if (res == -1) {
360 cleanup_dir(path, dir_files, 1);
361 return -1;
362 }
363
364 return 0;
365}
366
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000367int test_truncate(int len)
368{
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000369 const char *data = testdata;
370 int datalen = testdatalen;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000371 int res;
372
373 start_test("truncate(%u)", (int) len);
374 res = create_file(testfile, data, datalen);
375 if (res == -1)
376 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000377
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000378 res = truncate(testfile, len);
379 if (res == -1) {
380 PERROR("truncate");
381 return -1;
382 }
383 res = check_size(testfile, len);
384 if (res == -1)
385 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000386
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000387 if (len > 0) {
388 if (len <= datalen) {
389 res = check_data(testfile, data, 0, len);
390 if (res == -1)
391 return -1;
392 } else {
393 res = check_data(testfile, data, 0, datalen);
394 if (res == -1)
395 return -1;
396 res = check_data(testfile, zerodata, datalen, len - datalen);
397 if (res == -1)
398 return -1;
399 }
400 }
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000401 res = unlink(testfile);
402 if (res == -1) {
403 PERROR("unlink");
404 return -1;
405 }
406 res = check_nonexist(testfile2);
407 if (res == -1)
408 return -1;
409
410 success();
411 return 0;
412}
413
Miklos Szerediecce1bf2005-08-25 15:19:06 +0000414int test_ftruncate(int len, int mode)
415{
416 const char *data = testdata;
417 int datalen = testdatalen;
418 int res;
419 int fd;
420
421 start_test("ftruncate(%u) mode: 0%03o", len, mode);
422 res = create_file(testfile, data, datalen);
423 if (res == -1)
424 return -1;
425
426 fd = open(testfile, O_WRONLY);
427 if (fd == -1) {
428 PERROR("open");
429 return -1;
430 }
431
432 res = fchmod(fd, mode);
433 if (res == -1) {
434 PERROR("fchmod");
435 close(fd);
436 return -1;
437 }
438 res = check_mode(testfile, mode);
439 if (res == -1) {
440 close(fd);
441 return -1;
442 }
443 res = ftruncate(fd, len);
444 if (res == -1) {
445 PERROR("ftruncate");
446 close(fd);
447 return -1;
448 }
449 close(fd);
450 res = check_size(testfile, len);
451 if (res == -1)
452 return -1;
453
454 if (len > 0) {
455 if (len <= datalen) {
456 res = check_data(testfile, data, 0, len);
457 if (res == -1)
458 return -1;
459 } else {
460 res = check_data(testfile, data, 0, datalen);
461 if (res == -1)
462 return -1;
463 res = check_data(testfile, zerodata, datalen, len - datalen);
464 if (res == -1)
465 return -1;
466 }
467 }
468 res = unlink(testfile);
469 if (res == -1) {
470 PERROR("unlink");
471 return -1;
472 }
473 res = check_nonexist(testfile2);
474 if (res == -1)
475 return -1;
476
477 success();
478 return 0;
479}
480
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000481static int test_create(void)
482{
483 const char *data = testdata;
484 int datalen = testdatalen;
485 int err = 0;
486 int res;
487 int fd;
488
489 start_test("create");
490 unlink(testfile);
491 fd = creat(testfile, 0644);
492 if (fd == -1) {
493 PERROR("creat");
494 return -1;
495 }
496 res = write(fd, data, datalen);
497 if (res == -1) {
498 PERROR("write");
499 close(fd);
500 return -1;
501 }
502 if (res != datalen) {
503 ERROR("write is short: %u instead of %u", res, datalen);
504 close(fd);
505 return -1;
506 }
507 res = close(fd);
508 if (res == -1) {
509 PERROR("close");
510 return -1;
511 }
512 res = check_type(testfile, S_IFREG);
513 if (res == -1)
514 return -1;
515 err += check_mode(testfile, 0644);
516 err += check_nlink(testfile, 1);
517 err += check_size(testfile, datalen);
518 err += check_data(testfile, data, 0, datalen);
519 res = unlink(testfile);
520 if (res == -1) {
521 PERROR("unlink");
522 return -1;
523 }
524 res = check_nonexist(testfile);
525 if (res == -1)
526 return -1;
527 if (err)
528 return -1;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000529
530 success();
531 return 0;
532}
533
Miklos Szeredi02709512005-08-03 14:14:47 +0000534#define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
535
536static int do_test_open(int exist, int flags, const char *flags_str, int mode)
537{
538 char buf[4096];
539 const char *data = testdata;
540 int datalen = testdatalen;
541 unsigned currlen = 0;
542 int err = 0;
543 int res;
544 int fd;
545 off_t off;
546
547 start_test("open(%s, %s, 0%03o)", exist ? "+" : "-", flags_str, mode);
548 unlink(testfile);
549 if (exist) {
550 res = create_file(testfile, testdata2, testdata2len);
551 if (res == -1)
552 return -1;
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000553
Miklos Szeredi02709512005-08-03 14:14:47 +0000554 currlen = testdata2len;
555 }
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000556
Miklos Szeredi02709512005-08-03 14:14:47 +0000557 fd = open(testfile, flags, mode);
558 if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
559 if (fd != -1) {
560 ERROR("open should have failed");
561 close(fd);
562 return -1;
563 } else if (errno == EEXIST)
564 goto succ;
565 }
566 if (!(flags & O_CREAT) && !exist) {
567 if (fd != -1) {
568 ERROR("open should have failed");
569 close(fd);
570 return -1;
571 } else if (errno == ENOENT)
572 goto succ;
573 }
574 if (fd == -1) {
575 PERROR("open");
576 return -1;
577 }
578
579 if (flags & O_TRUNC)
580 currlen = 0;
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000581
Miklos Szeredi02709512005-08-03 14:14:47 +0000582 err += check_type(testfile, S_IFREG);
583 if (exist)
584 err += check_mode(testfile, 0644);
585 else
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000586 err += check_mode(testfile, mode);
Miklos Szeredi02709512005-08-03 14:14:47 +0000587 err += check_nlink(testfile, 1);
588 err += check_size(testfile, currlen);
589 if (exist && !(flags & O_TRUNC) && (mode & 0400))
590 err += check_data(testfile, testdata2, 0, testdata2len);
591
592 res = write(fd, data, datalen);
593 if ((flags & O_ACCMODE) != O_RDONLY) {
594 if (res == -1) {
595 PERROR("write");
596 err --;
597 } else if (res != datalen) {
598 ERROR("write is short: %u instead of %u", res, datalen);
599 err --;
600 } else {
601 if (datalen > (int) currlen)
602 currlen = datalen;
603
604 err += check_size(testfile, currlen);
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000605
Miklos Szeredi02709512005-08-03 14:14:47 +0000606 if (mode & 0400) {
607 err += check_data(testfile, data, 0, datalen);
608 if (exist && !(flags & O_TRUNC) && testdata2len > datalen)
609 err += check_data(testfile, testdata2 + datalen, datalen,
610 testdata2len - datalen);
611 }
612 }
613 } else {
614 if (res != -1) {
615 ERROR("write should have failed");
616 err --;
617 } else if (errno != EBADF) {
618 PERROR("write");
619 err --;
620 }
621 }
622 off = lseek(fd, SEEK_SET, 0);
623 if (off == (off_t) -1) {
624 PERROR("lseek");
625 err--;
626 } else if (off != 0) {
627 ERROR("offset should have returned 0");
628 err --;
629 }
630 res = read(fd, buf, sizeof(buf));
631 if ((flags & O_ACCMODE) != O_WRONLY) {
632 if (res == -1) {
633 PERROR("read");
634 err--;
635 } else {
636 int readsize = currlen < sizeof(buf) ? currlen : sizeof(buf);
637 if (res != readsize) {
638 ERROR("read is short: %i instead of %u", res, readsize);
639 err--;
640 } else {
641 if ((flags & O_ACCMODE) != O_RDONLY) {
642 err += check_buffer(buf, data, datalen);
643 if (exist && !(flags & O_TRUNC) && testdata2len > datalen)
644 err += check_buffer(buf + datalen, testdata2 + datalen,
645 testdata2len - datalen);
646 } else if (exist)
647 err += check_buffer(buf, testdata2, testdata2len);
648 }
649 }
650 } else {
651 if (res != -1) {
652 ERROR("read should have failed");
653 err --;
654 } else if (errno != EBADF) {
655 PERROR("read");
656 err --;
657 }
658 }
659
660 res = close(fd);
661 if (res == -1) {
662 PERROR("close");
663 return -1;
664 }
665 res = unlink(testfile);
666 if (res == -1) {
667 PERROR("unlink");
668 return -1;
669 }
670 res = check_nonexist(testfile);
671 if (res == -1)
672 return -1;
673 if (err)
674 return -1;
675
676 succ:
677 success();
678 return 0;
679}
680
Miklos Szerediecce1bf2005-08-25 15:19:06 +0000681#define test_open_acc(flags, mode, err) do_test_open_acc(flags, #flags, mode, err)
682
683static int do_test_open_acc(int flags, const char *flags_str, int mode, int err)
684{
685 const char *data = testdata;
686 int datalen = testdatalen;
687 int res;
688 int fd;
689
690 start_test("open_acc(%s) mode: 0%03o error: '%s'", flags_str, mode,
691 strerror(err));
692 unlink(testfile);
693 res = create_file(testfile, data, datalen);
694 if (res == -1)
695 return -1;
696
697 res = chmod(testfile, mode);
698 if (res == -1) {
699 PERROR("chmod");
700 return -1;
701 }
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000702
Miklos Szerediecce1bf2005-08-25 15:19:06 +0000703 res = check_mode(testfile, mode);
704 if (res == -1)
705 return -1;
706
707 fd = open(testfile, flags);
708 if (fd == -1) {
709 if (err != errno) {
710 PERROR("open");
711 return -1;
712 }
713 } else {
714 if (err) {
715 ERROR("open should have failed");
716 close(fd);
717 return -1;
718 }
719 close(fd);
720 }
721 success();
722 return 0;
723}
Miklos Szeredi02709512005-08-03 14:14:47 +0000724
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000725static int test_symlink(void)
726{
727 char buf[1024];
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000728 const char *data = testdata;
729 int datalen = testdatalen;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000730 int linklen = strlen(testfile);
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000731 int err = 0;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000732 int res;
733
734 start_test("symlink");
735 res = create_file(testfile, data, datalen);
736 if (res == -1)
737 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000738
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000739 unlink(testfile2);
740 res = symlink(testfile, testfile2);
741 if (res == -1) {
742 PERROR("symlink");
743 return -1;
744 }
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000745 res = check_type(testfile2, S_IFLNK);
746 if (res == -1)
747 return -1;
748 err += check_mode(testfile2, 0777);
749 err += check_nlink(testfile2, 1);
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000750 res = readlink(testfile2, buf, sizeof(buf));
751 if (res == -1) {
752 PERROR("readlink");
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000753 err--;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000754 }
755 if (res != linklen) {
756 ERROR("short readlink: %u instead of %u", res, linklen);
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000757 err--;
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000758 }
759 if (memcmp(buf, testfile, linklen) != 0) {
760 ERROR("link mismatch");
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000761 err--;
762 }
763 err += check_size(testfile2, datalen);
764 err += check_data(testfile2, data, 0, datalen);
765 res = unlink(testfile2);
766 if (res == -1) {
767 PERROR("unlink");
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000768 return -1;
769 }
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000770 res = check_nonexist(testfile2);
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000771 if (res == -1)
772 return -1;
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000773 if (err)
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000774 return -1;
775
776 success();
777 return 0;
778}
779
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000780static int test_rename_file(void)
Miklos Szeredi3b206c72005-05-06 10:15:26 +0000781{
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000782 const char *data = testdata;
783 int datalen = testdatalen;
784 int err = 0;
785 int res;
786
787 start_test("rename file");
788 res = create_file(testfile, data, datalen);
789 if (res == -1)
790 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000791
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000792 unlink(testfile2);
793 res = rename(testfile, testfile2);
794 if (res == -1) {
795 PERROR("rename");
796 return -1;
797 }
798 res = check_nonexist(testfile);
799 if (res == -1)
800 return -1;
801 res = check_type(testfile2, S_IFREG);
802 if (res == -1)
803 return -1;
804 err += check_mode(testfile2, 0644);
805 err += check_nlink(testfile2, 1);
806 err += check_size(testfile2, datalen);
807 err += check_data(testfile2, data, 0, datalen);
808 res = unlink(testfile2);
809 if (res == -1) {
810 PERROR("unlink");
811 return -1;
812 }
813 res = check_nonexist(testfile2);
814 if (res == -1)
815 return -1;
816 if (err)
817 return -1;
818
819 success();
820 return 0;
821}
822
823static int test_rename_dir(void)
824{
825 int err = 0;
826 int res;
827
828 start_test("rename dir");
829 res = create_dir(testdir, testdir_files);
830 if (res == -1)
831 return -1;
Miklos Szeredi9b813af2005-07-21 07:59:37 +0000832
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000833 rmdir(testdir2);
834 res = rename(testdir, testdir2);
835 if (res == -1) {
836 PERROR("rename");
837 cleanup_dir(testdir, testdir_files, 1);
838 return -1;
839 }
840 res = check_nonexist(testdir);
841 if (res == -1) {
842 cleanup_dir(testdir, testdir_files, 1);
843 return -1;
844 }
845 res = check_type(testdir2, S_IFDIR);
846 if (res == -1) {
847 cleanup_dir(testdir2, testdir_files, 1);
848 return -1;
849 }
850 err += check_mode(testdir2, 0755);
851 err += check_dir_contents(testdir2, testdir_files);
852 err += cleanup_dir(testdir2, testdir_files, 0);
853 res = rmdir(testdir2);
854 if (res == -1) {
855 PERROR("rmdir");
856 return -1;
857 }
858 res = check_nonexist(testdir2);
859 if (res == -1)
860 return -1;
861 if (err)
862 return -1;
863
864 success();
865 return 0;
866}
867
868int test_mkfifo(void)
869{
870 int res;
871 int err = 0;
872
873 start_test("mkfifo");
874 unlink(testfile);
875 res = mkfifo(testfile, 0644);
876 if (res == -1) {
877 PERROR("mkfifo");
878 return -1;
879 }
880 res = check_type(testfile, S_IFIFO);
881 if (res == -1)
882 return -1;
883 err += check_mode(testfile, 0644);
884 err += check_nlink(testfile, 1);
885 res = unlink(testfile);
886 if (res == -1) {
887 PERROR("unlink");
888 return -1;
889 }
890 res = check_nonexist(testfile);
891 if (res == -1)
892 return -1;
893 if (err)
894 return -1;
895
896 success();
897 return 0;
898}
899
900int test_mkdir(void)
901{
902 int res;
903 int err = 0;
904 const char *dir_contents[] = {NULL};
905
906 start_test("mkdir");
907 rmdir(testdir);
908 res = mkdir(testdir, 0755);
909 if (res == -1) {
910 PERROR("mkdir");
911 return -1;
912 }
913 res = check_type(testdir, S_IFDIR);
914 if (res == -1)
915 return -1;
916 err += check_mode(testdir, 0755);
917 err += check_nlink(testdir, 2);
918 err += check_dir_contents(testdir, dir_contents);
919 res = rmdir(testdir);
920 if (res == -1) {
921 PERROR("rmdir");
922 return -1;
923 }
924 res = check_nonexist(testdir);
925 if (res == -1)
926 return -1;
927 if (err)
928 return -1;
929
930 success();
931 return 0;
932}
933
934int main(int argc, char *argv[])
935{
936 const char *basepath;
937 int err = 0;
938
Miklos Szeredi02709512005-08-03 14:14:47 +0000939 umask(0);
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000940 if (argc != 2) {
941 fprintf(stderr, "usage: %s testdir\n", argv[0]);
942 return 1;
943 }
944 basepath = argv[1];
945 assert(strlen(basepath) < 512);
Miklos Szeredi2bb750e2005-10-03 14:54:24 +0000946
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +0000947 sprintf(testfile, "%s/testfile", basepath);
948 sprintf(testfile2, "%s/testfile2", basepath);
949 sprintf(testdir, "%s/testdir", basepath);
950 sprintf(testdir2, "%s/testdir2", basepath);
951 err += test_create();
952 err += test_symlink();
953 err += test_mkfifo();
954 err += test_mkdir();
955 err += test_rename_file();
956 err += test_rename_dir();
957 err += test_truncate(0);
958 err += test_truncate(testdatalen / 2);
959 err += test_truncate(testdatalen);
960 err += test_truncate(testdatalen + 100);
Miklos Szerediecce1bf2005-08-25 15:19:06 +0000961 err += test_ftruncate(0, 0600);
962 err += test_ftruncate(testdatalen / 2, 0600);
963 err += test_ftruncate(testdatalen, 0600);
964 err += test_ftruncate(testdatalen + 100, 0600);
965 err += test_ftruncate(0, 0400);
966 err += test_ftruncate(0, 0200);
967 err += test_ftruncate(0, 0000);
Miklos Szeredi02709512005-08-03 14:14:47 +0000968 err += test_open(0, O_RDONLY, 0);
969 err += test_open(1, O_RDONLY, 0);
970 err += test_open(1, O_RDWR, 0);
971 err += test_open(1, O_WRONLY, 0);
972 err += test_open(0, O_RDWR | O_CREAT, 0600);
973 err += test_open(1, O_RDWR | O_CREAT, 0600);
974 err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
975 err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
976 err += test_open(0, O_RDONLY | O_CREAT, 0600);
977 err += test_open(0, O_RDONLY | O_CREAT, 0400);
978 err += test_open(0, O_RDONLY | O_CREAT, 0200);
979 err += test_open(0, O_RDONLY | O_CREAT, 0000);
980 err += test_open(0, O_WRONLY | O_CREAT, 0600);
981 err += test_open(0, O_WRONLY | O_CREAT, 0400);
982 err += test_open(0, O_WRONLY | O_CREAT, 0200);
983 err += test_open(0, O_WRONLY | O_CREAT, 0000);
984 err += test_open(0, O_RDWR | O_CREAT, 0400);
985 err += test_open(0, O_RDWR | O_CREAT, 0200);
986 err += test_open(0, O_RDWR | O_CREAT, 0000);
987 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
988 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
Miklos Szeredi17c24712005-08-05 17:00:50 +0000989 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
990 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
Miklos Szerediecce1bf2005-08-25 15:19:06 +0000991 err += test_open_acc(O_RDONLY, 0600, 0);
992 err += test_open_acc(O_WRONLY, 0600, 0);
993 err += test_open_acc(O_RDWR, 0600, 0);
994 err += test_open_acc(O_RDONLY, 0400, 0);
995 err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
996 err += test_open_acc(O_WRONLY, 0400, EACCES);
997 err += test_open_acc(O_RDWR, 0400, EACCES);
998 err += test_open_acc(O_RDONLY, 0200, EACCES);
999 err += test_open_acc(O_WRONLY, 0200, 0);
1000 err += test_open_acc(O_RDWR, 0200, EACCES);
1001 err += test_open_acc(O_RDONLY, 0000, EACCES);
1002 err += test_open_acc(O_WRONLY, 0000, EACCES);
1003 err += test_open_acc(O_RDWR, 0000, EACCES);
Miklos Szeredi2bb750e2005-10-03 14:54:24 +00001004
Miklos Szeredi0fc4abe2005-05-10 16:10:05 +00001005 unlink(testfile);
1006 unlink(testfile2);
1007 rmdir(testdir);
1008 rmdir(testdir2);
1009
1010 if (err)
1011 return 1;
1012
Miklos Szeredi3b206c72005-05-06 10:15:26 +00001013 return 0;
1014}