[asan] Revert r201402, r201404.
[blocksruntime.git] / lib / msan / lit_tests / Linux / xattr.cc
blob583b2e3a9bdd874506e5702dfe81251ee64180fd
1 // RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p 2>&1
2 // RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %t %p 2>&1
3 // RUN: %clangxx_msan -m64 -O3 %s -o %t && %t %p 2>&1
5 #include <argz.h>
6 #include <assert.h>
7 #include <sys/types.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include <sanitizer/msan_interface.h>
16 // Do not depend on libattr headers.
17 #ifndef ENOATTR
18 #define ENOATTR ENODATA
19 #endif
21 extern "C" {
22 ssize_t listxattr(const char *path, char *list, size_t size);
23 ssize_t llistxattr(const char *path, char *list, size_t size);
24 ssize_t flistxattr(int fd, char *list, size_t size);
25 ssize_t getxattr(const char *path, const char *name, void *value, size_t size);
26 ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size);
27 ssize_t fgetxattr(int fd, const char *name, void *value, size_t size);
30 char g_path[1024];
31 int g_fd;
33 // Life before closures...
34 ssize_t listxattr_wrapper(char *buf, size_t size) {
35 return listxattr(g_path, buf, size);
38 ssize_t llistxattr_wrapper(char *buf, size_t size) {
39 return llistxattr(g_path, buf, size);
42 ssize_t flistxattr_wrapper(char *buf, size_t size) {
43 return flistxattr(g_fd, buf, size);
46 ssize_t getxattr_wrapper(const char *name, char *buf, size_t size) {
47 return getxattr(g_path, name, buf, size);
50 ssize_t lgetxattr_wrapper(const char *name, char *buf, size_t size) {
51 return lgetxattr(g_path, name, buf, size);
54 ssize_t fgetxattr_wrapper(const char *name, char *buf, size_t size) {
55 return fgetxattr(g_fd, name, buf, size);
58 size_t test_list(ssize_t fun(char*, size_t), char **buf) {
59 int buf_size = 1024;
60 while (true) {
61 *buf = (char *)malloc(buf_size);
62 assert(__msan_test_shadow(*buf, buf_size) != -1);
63 ssize_t res = fun(*buf, buf_size);
64 if (res >= 0) {
65 assert(__msan_test_shadow(*buf, buf_size) == res);
66 return res;
68 if (errno == ENOTSUP) {
69 printf("Extended attributes are disabled. *xattr test is a no-op.\n");
70 exit(0);
72 assert(errno == ERANGE);
73 free(*buf);
74 buf_size *= 2;
78 // True means success. False means result inconclusive because we don't have
79 // access to this attribute.
80 bool test_get_single_attr(ssize_t fun(const char *, char *, size_t),
81 const char *attr_name) {
82 char *buf;
83 int buf_size = 1024;
84 while (true) {
85 buf = (char *)malloc(buf_size);
86 assert(__msan_test_shadow(buf, buf_size) != -1);
87 ssize_t res = fun(attr_name, buf, buf_size);
88 if (res >= 0) {
89 assert(__msan_test_shadow(buf, buf_size) == res);
90 free(buf);
91 return true;
93 if (errno == ENOTSUP) {
94 printf("Extended attributes are disabled. *xattr test is a no-op.\n");
95 exit(0);
97 if (errno == ENOATTR)
98 return false;
99 assert(errno == ERANGE);
100 free(buf);
101 buf_size *= 2;
105 void test_get(ssize_t fun(const char *, char *, size_t), const char *attr_list,
106 size_t attr_list_size) {
107 // Try every attribute, until we see one we can access. Attribute names are
108 // null-separated strings in attr_list.
109 size_t attr_list_len = argz_count(attr_list, attr_list_size);
110 char **attrs = (char **)malloc((attr_list_len + 1) * sizeof(char *));
111 size_t i;
112 for (i = 0; (i < attr_list_len) && attrs[i]; i++) {
113 if (test_get_single_attr(fun, attrs[i]))
114 return;
116 printf("*xattr test could not access any attributes.\n");
119 // TODO: set some attributes before trying to retrieve them with *getxattr.
120 // Currently the list is empty, so *getxattr is not tested.
121 int main(int argc, char *argv[]) {
122 assert(argc == 2);
123 snprintf(g_path, sizeof(g_path), "%s/%s", argv[1], "xattr_test_root/a");
125 g_fd = open(g_path, O_RDONLY);
126 assert(g_fd);
128 char *attr_list;
129 size_t attr_list_size;
130 attr_list_size = test_list(listxattr_wrapper, &attr_list);
131 free(attr_list);
132 attr_list_size = test_list(llistxattr_wrapper, &attr_list);
133 free(attr_list);
134 attr_list_size = test_list(flistxattr_wrapper, &attr_list);
136 test_get(getxattr_wrapper, attr_list, attr_list_size);
137 test_get(lgetxattr_wrapper, attr_list, attr_list_size);
138 test_get(fgetxattr_wrapper, attr_list, attr_list_size);
140 free(attr_list);
141 return 0;