]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
ac229ed8 RC |
2 | |
3 | #include <errno.h> | |
4 | #include <fcntl.h> | |
5 | #include <sys/types.h> | |
6 | #include <sys/xattr.h> | |
7 | #include <unistd.h> | |
8 | ||
9 | #include "alloc-util.h" | |
10 | #include "fd-util.h" | |
11 | #include "fs-util.h" | |
12 | #include "macro.h" | |
c56c26c9 | 13 | #include "rm-rf.h" |
ac229ed8 | 14 | #include "string-util.h" |
6d7c4033 | 15 | #include "tests.h" |
e4de7287 | 16 | #include "tmpfile-util.h" |
ac229ed8 RC |
17 | #include "xattr-util.h" |
18 | ||
4f7452a8 | 19 | TEST(getxattr_at_malloc) { |
c56c26c9 | 20 | _cleanup_(rm_rf_physical_and_freep) char *t = NULL; |
5ce46344 | 21 | _cleanup_free_ char *value = NULL; |
254d1313 | 22 | _cleanup_close_ int fd = -EBADF; |
ac229ed8 | 23 | const char *x; |
ac229ed8 RC |
24 | int r; |
25 | ||
c56c26c9 YW |
26 | fd = mkdtemp_open("/var/tmp/test-xattrtestXXXXXX", O_RDONLY|O_NOCTTY, &t); |
27 | assert_se(fd >= 0); | |
ac229ed8 RC |
28 | x = strjoina(t, "/test"); |
29 | assert_se(touch(x) >= 0); | |
30 | ||
31 | r = setxattr(x, "user.foo", "bar", 3, 0); | |
c56c26c9 YW |
32 | if (r < 0 && ERRNO_IS_NOT_SUPPORTED(errno)) |
33 | return (void) log_tests_skipped_errno(errno, "no xattrs supported on /var/tmp"); | |
ac229ed8 RC |
34 | assert_se(r >= 0); |
35 | ||
c53e07e2 LP |
36 | assert_se(getxattr_at_malloc(fd, "test", "user.foo", 0, &value) == 3); |
37 | assert_se(memcmp(value, "bar", 3) == 0); | |
38 | value = mfree(value); | |
39 | ||
40 | assert_se(getxattr_at_malloc(AT_FDCWD, x, "user.foo", 0, &value) == 3); | |
41 | assert_se(memcmp(value, "bar", 3) == 0); | |
42 | value = mfree(value); | |
ac229ed8 RC |
43 | |
44 | safe_close(fd); | |
45 | fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY); | |
46 | assert_se(fd >= 0); | |
c53e07e2 | 47 | r = getxattr_at_malloc(fd, "usr", "user.idontexist", 0, &value); |
6f8b3838 | 48 | assert_se(ERRNO_IS_NEG_XATTR_ABSENT(r)); |
ac229ed8 | 49 | |
5ce46344 LB |
50 | safe_close(fd); |
51 | fd = open(x, O_PATH|O_CLOEXEC); | |
52 | assert_se(fd >= 0); | |
c53e07e2 | 53 | assert_se(getxattr_at_malloc(fd, NULL, "user.foo", 0, &value) == 3); |
c79e88b3 | 54 | ASSERT_STREQ(value, "bar"); |
ac229ed8 RC |
55 | } |
56 | ||
4f7452a8 | 57 | TEST(getcrtime) { |
c56c26c9 | 58 | _cleanup_(rm_rf_physical_and_freep) char *t = NULL; |
254d1313 | 59 | _cleanup_close_ int fd = -EBADF; |
4c2e1b39 LP |
60 | usec_t usec, k; |
61 | int r; | |
62 | ||
c56c26c9 | 63 | fd = mkdtemp_open("/var/tmp/test-xattrtestXXXXXX", 0, &t); |
4c2e1b39 LP |
64 | assert_se(fd >= 0); |
65 | ||
66 | r = fd_getcrtime(fd, &usec); | |
67 | if (r < 0) | |
68 | log_debug_errno(r, "btime: %m"); | |
69 | else | |
04f5c018 | 70 | log_debug("btime: %s", FORMAT_TIMESTAMP(usec)); |
4c2e1b39 LP |
71 | |
72 | k = now(CLOCK_REALTIME); | |
73 | ||
74 | r = fd_setcrtime(fd, 1519126446UL * USEC_PER_SEC); | |
75 | if (!IN_SET(r, -EOPNOTSUPP, -ENOTTY)) { | |
76 | assert_se(fd_getcrtime(fd, &usec) >= 0); | |
77 | assert_se(k < 1519126446UL * USEC_PER_SEC || | |
78 | usec == 1519126446UL * USEC_PER_SEC); | |
79 | } | |
80 | } | |
81 | ||
d7e32d05 YW |
82 | static void verify_xattr(int dfd, const char *expected) { |
83 | _cleanup_free_ char *value = NULL; | |
84 | ||
85 | assert_se(getxattr_at_malloc(dfd, "test", "user.foo", 0, &value) == (int) strlen(expected)); | |
c79e88b3 | 86 | ASSERT_STREQ(value, expected); |
d7e32d05 YW |
87 | } |
88 | ||
89 | TEST(xsetxattr) { | |
90 | _cleanup_(rm_rf_physical_and_freep) char *t = NULL; | |
91 | _cleanup_close_ int dfd = -EBADF, fd = -EBADF; | |
92 | const char *x; | |
93 | int r; | |
94 | ||
95 | dfd = mkdtemp_open("/var/tmp/test-xattrtestXXXXXX", O_PATH, &t); | |
96 | assert_se(dfd >= 0); | |
97 | x = strjoina(t, "/test"); | |
98 | assert_se(touch(x) >= 0); | |
99 | ||
100 | /* by full path */ | |
101 | r = xsetxattr(AT_FDCWD, x, "user.foo", "fullpath", SIZE_MAX, 0); | |
6f8b3838 | 102 | if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) |
d7e32d05 YW |
103 | return (void) log_tests_skipped_errno(r, "no xattrs supported on /var/tmp"); |
104 | assert_se(r >= 0); | |
105 | verify_xattr(dfd, "fullpath"); | |
106 | ||
107 | /* by dirfd */ | |
108 | assert_se(xsetxattr(dfd, "test", "user.foo", "dirfd", SIZE_MAX, 0) >= 0); | |
109 | verify_xattr(dfd, "dirfd"); | |
110 | ||
111 | /* by fd (O_PATH) */ | |
112 | fd = openat(dfd, "test", O_PATH|O_CLOEXEC); | |
113 | assert_se(fd >= 0); | |
114 | assert_se(xsetxattr(fd, NULL, "user.foo", "fd_opath", SIZE_MAX, 0) >= 0); | |
115 | verify_xattr(dfd, "fd_opath"); | |
116 | assert_se(xsetxattr(fd, "", "user.foo", "fd_opath", SIZE_MAX, 0) == -EINVAL); | |
117 | assert_se(xsetxattr(fd, "", "user.foo", "fd_opath_empty", SIZE_MAX, AT_EMPTY_PATH) >= 0); | |
118 | verify_xattr(dfd, "fd_opath_empty"); | |
119 | fd = safe_close(fd); | |
120 | ||
121 | fd = openat(dfd, "test", O_RDONLY|O_CLOEXEC); | |
122 | assert_se(xsetxattr(fd, NULL, "user.foo", "fd_regular", SIZE_MAX, 0) >= 0); | |
123 | verify_xattr(dfd, "fd_regular"); | |
124 | assert_se(xsetxattr(fd, "", "user.foo", "fd_regular_empty", SIZE_MAX, 0) == -EINVAL); | |
125 | assert_se(xsetxattr(fd, "", "user.foo", "fd_regular_empty", SIZE_MAX, AT_EMPTY_PATH) >= 0); | |
126 | verify_xattr(dfd, "fd_regular_empty"); | |
127 | } | |
128 | ||
4f7452a8 | 129 | DEFINE_TEST_MAIN(LOG_DEBUG); |