diff options
Diffstat (limited to 'openbsd-compat/regress/utimensattest.c')
-rw-r--r-- | openbsd-compat/regress/utimensattest.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c index a7bc7634b..24312e5d8 100644 --- a/openbsd-compat/regress/utimensattest.c +++ b/openbsd-compat/regress/utimensattest.c | |||
@@ -33,7 +33,14 @@ | |||
33 | 33 | ||
34 | int utimensat(int, const char *, const struct timespec[2], int); | 34 | int utimensat(int, const char *, const struct timespec[2], int); |
35 | 35 | ||
36 | void | 36 | static void |
37 | cleanup(void) | ||
38 | { | ||
39 | (void)unlink(TMPFILE); | ||
40 | (void)unlink(TMPFILE2); | ||
41 | } | ||
42 | |||
43 | static void | ||
37 | fail(char *msg, long expect, long got) | 44 | fail(char *msg, long expect, long got) |
38 | { | 45 | { |
39 | int saved_errno = errno; | 46 | int saved_errno = errno; |
@@ -44,6 +51,7 @@ fail(char *msg, long expect, long got) | |||
44 | else | 51 | else |
45 | fprintf(stderr, "utimensat: %s: expected %ld got %ld\n", | 52 | fprintf(stderr, "utimensat: %s: expected %ld got %ld\n", |
46 | msg, expect, got); | 53 | msg, expect, got); |
54 | cleanup(); | ||
47 | exit(1); | 55 | exit(1); |
48 | } | 56 | } |
49 | 57 | ||
@@ -54,6 +62,7 @@ main(void) | |||
54 | struct stat sb; | 62 | struct stat sb; |
55 | struct timespec ts[2]; | 63 | struct timespec ts[2]; |
56 | 64 | ||
65 | cleanup(); | ||
57 | if ((fd = open(TMPFILE, O_CREAT, 0600)) == -1) | 66 | if ((fd = open(TMPFILE, O_CREAT, 0600)) == -1) |
58 | fail("open", 0, 0); | 67 | fail("open", 0, 0); |
59 | close(fd); | 68 | close(fd); |
@@ -83,15 +92,27 @@ main(void) | |||
83 | fail("mtim.tv_nsec", 45678000, sb.st_mtim.tv_nsec); | 92 | fail("mtim.tv_nsec", 45678000, sb.st_mtim.tv_nsec); |
84 | #endif | 93 | #endif |
85 | 94 | ||
95 | /* | ||
96 | * POSIX specifies that when given a symlink, AT_SYMLINK_NOFOLLOW | ||
97 | * should update the symlink and not the destination. The compat | ||
98 | * code doesn't have a way to do this, so where possible it fails | ||
99 | * with instead of following a symlink when explicitly asked not to. | ||
100 | * Here we just test that it does not update the destination. | ||
101 | */ | ||
86 | if (rename(TMPFILE, TMPFILE2) == -1) | 102 | if (rename(TMPFILE, TMPFILE2) == -1) |
87 | fail("rename", 0, 0); | 103 | fail("rename", 0, 0); |
88 | if (symlink(TMPFILE2, TMPFILE) == -1) | 104 | if (symlink(TMPFILE2, TMPFILE) == -1) |
89 | fail("symlink", 0, 0); | 105 | fail("symlink", 0, 0); |
106 | ts[0].tv_sec = 11223344; | ||
107 | ts[1].tv_sec = 55667788; | ||
108 | (void)utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW); | ||
109 | if (stat(TMPFILE2, &sb) == -1) | ||
110 | fail("stat", 0, 0 ); | ||
111 | if (sb.st_atime == 11223344) | ||
112 | fail("utimensat symlink st_atime", 0, 0 ); | ||
113 | if (sb.st_mtime == 55667788) | ||
114 | fail("utimensat symlink st_mtime", 0, 0 ); | ||
90 | 115 | ||
91 | if (utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW) != -1) | 116 | cleanup(); |
92 | fail("utimensat followed symlink", 0, 0); | ||
93 | |||
94 | if (!(unlink(TMPFILE) == 0 && unlink(TMPFILE2) == 0)) | ||
95 | fail("unlink", 0, 0); | ||
96 | exit(0); | 117 | exit(0); |
97 | } | 118 | } |