1 /* vi: set sw=4 ts=4: */
2 /* testcase for futimens(2)
3 * Copyright (C) 2009 Bernhard Reutner-Fischer <uClibc@uClibc.org>
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <unistd.h>
13
14 struct
15 {
16 char *name; /* name of file to open */
17 int flags; /* flags for file descriptor */
18 const struct timespec ts[2];
19 int err; /* expected errno */
20 } tests [] =
21 {
22 {"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{0,0}}, 0},
23 {"futimens.tst", (O_CREAT|O_TRUNC), {{99,0},{0,0}}, 0},
24 {"futimens.tst", (O_CREAT|O_TRUNC), {{0,99},{0,0}}, 0},
25 {"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{99,0}}, 0},
26 {"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{0,99}}, 0},
27 {"futimens.tst", (O_CREAT|O_TRUNC), {{11,2},{3,4}}, 0},
28 };
do_test(int argc,char ** argv)29 int do_test(int argc, char **argv) {
30 char *name;
31 int i, errors;
32 errors = argc - argc + 0;
33 unsigned has_stat_nsec = 0;
34 {
35 struct stat probe;
36 /* Let's attempt an educated guess if this filesystem supports
37 * nanosecond mtime. */
38 if ((!stat(".", &probe)) && probe.st_mtim.tv_nsec)
39 has_stat_nsec = 1;
40 else if ((!stat(argv[0], &probe)) && probe.st_mtim.tv_nsec)
41 has_stat_nsec = 1;
42 }
43 for (i=0; i < (int) (sizeof(tests)/sizeof(tests[0])); ++i) {
44 int err, fd;
45 struct stat sb;
46 name = tests[i].name;
47 if (*name != '.')
48 unlink(name);
49 fd = open(name, tests[i].flags, 0660);
50 if (fd < 0)
51 abort();
52 errno = 0;
53 err = futimens(fd, tests[i].ts);
54 if ((errno && !err) || (!errno && err)) {
55 err = errno;
56 printf("FAILED test %d (errno and return value disagree)\n", i);
57 ++errors;
58 } else
59 err = errno;
60 if (err != tests[i].err) {
61 printf("FAILED test %d (expected errno %d, got %d)\n",
62 i, tests[i].err, err);
63 ++errors;
64 continue;
65 }
66 if (stat(name, &sb) < 0) {
67 printf("FAILED test %d (verification)\n", i);
68 ++errors;
69 continue;
70 } else {
71 unsigned wrong = tests[i].ts[0].tv_sec != sb.st_atim.tv_sec ||
72 tests[i].ts[0].tv_nsec != sb.st_atim.tv_nsec ||
73 tests[i].ts[1].tv_sec != sb.st_mtim.tv_sec ||
74 tests[i].ts[1].tv_nsec != sb.st_mtim.tv_nsec;
75 if (wrong) {
76 if (tests[i].ts[0].tv_sec != sb.st_atim.tv_sec) {
77 printf("FAILED test %d (access time, sec: expected %ld, got %ld)\n",
78 i, tests[i].ts[0].tv_sec, sb.st_atim.tv_sec);
79 ++errors;
80 }
81 if (tests[i].ts[0].tv_nsec != sb.st_atim.tv_nsec) {
82 printf("FAILED test %d (access time, nsec: expected %ld, got %ld)\n",
83 i, tests[i].ts[0].tv_nsec, sb.st_atim.tv_nsec);
84 errors += has_stat_nsec;
85 }
86
87 if (tests[i].ts[1].tv_sec != sb.st_mtim.tv_sec) {
88 printf("FAILED test %d (modification time, sec: expected %ld, got %ld)\n",
89 i, tests[i].ts[1].tv_sec, sb.st_mtim.tv_sec);
90 ++errors;
91 }
92 if (tests[i].ts[1].tv_nsec != sb.st_mtim.tv_nsec) {
93 printf("FAILED test %d (modification time, nsec: expected %ld, got %ld)\n",
94 i, tests[i].ts[1].tv_nsec, sb.st_mtim.tv_nsec);
95 errors += has_stat_nsec;
96 }
97 }
98 }
99 }
100 if (*name != '.')
101 unlink(name);
102 printf("%d errors.\n", errors);
103 return (!errors) ? EXIT_SUCCESS : EXIT_FAILURE;
104 }
105 #include <test-skeleton.c>
106