1 #include <assert.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "uv.h"
5 #include "uvwasi.h"
6 #include "wasi_serdes.h"
7
8 #define TEST_TMP_DIR "./out/tmp"
9 #define TEST_PATH_READDIR TEST_TMP_DIR "/test_readdir"
10 #define TEST_PATH_FILE_1 TEST_PATH_READDIR "/test_file_1"
11 #define TEST_PATH_FILE_2 TEST_PATH_READDIR "/test_file_2"
12
13
14 #if !defined(_WIN32) && !defined(__ANDROID__)
touch_file(const char * name)15 static void touch_file(const char* name) {
16 uv_fs_t req;
17 int r;
18
19 r = uv_fs_open(NULL,
20 &req,
21 name,
22 O_WRONLY | O_CREAT | O_TRUNC,
23 S_IWUSR | S_IRUSR,
24 NULL);
25 uv_fs_req_cleanup(&req);
26 assert(r >= 0);
27 r = uv_fs_close(NULL, &req, r, NULL);
28 uv_fs_req_cleanup(&req);
29 assert(r == 0);
30 }
31 #endif /* !defined(_WIN32) && !defined(__ANDROID__) */
32
33
main(void)34 int main(void) {
35 #if !defined(_WIN32) && !defined(__ANDROID__)
36 uvwasi_t uvwasi;
37 uvwasi_options_t init_options;
38 uvwasi_dircookie_t cookie;
39 uvwasi_dirent_t dirent;
40 uvwasi_size_t buf_size;
41 uvwasi_size_t buf_used;
42 uvwasi_errno_t err;
43 uv_fs_t req;
44 char buf[1024];
45 char* name;
46 int r;
47
48 r = uv_fs_mkdir(NULL, &req, TEST_TMP_DIR, 0777, NULL);
49 uv_fs_req_cleanup(&req);
50 assert(r == 0 || r == UV_EEXIST);
51
52 r = uv_fs_mkdir(NULL, &req, TEST_PATH_READDIR, 0777, NULL);
53 uv_fs_req_cleanup(&req);
54 assert(r == 0 || r == UV_EEXIST);
55
56 touch_file(TEST_PATH_FILE_1);
57 touch_file(TEST_PATH_FILE_2);
58
59 uvwasi_options_init(&init_options);
60 init_options.preopenc = 1;
61 init_options.preopens = calloc(1, sizeof(uvwasi_preopen_t));
62 init_options.preopens[0].mapped_path = "/var";
63 init_options.preopens[0].real_path = TEST_PATH_READDIR;
64
65 err = uvwasi_init(&uvwasi, &init_options);
66 assert(err == 0);
67
68 buf_size = 1024;
69
70 /* Verify uvwasi_fd_readdir() behavior with insufficient buffer space. */
71 memset(buf, 0, buf_size);
72 buf_used = 0;
73 cookie = UVWASI_DIRCOOKIE_START;
74 err = uvwasi_fd_readdir(&uvwasi,
75 3,
76 &buf,
77 UVWASI_SERDES_SIZE_dirent_t + 10,
78 cookie,
79 &buf_used);
80 assert(err == 0);
81 assert(buf_used == UVWASI_SERDES_SIZE_dirent_t + 10);
82 uvwasi_serdes_read_dirent_t(buf, 0, &dirent);
83 assert(dirent.d_ino == 0);
84 assert(dirent.d_namlen == 11);
85 assert(dirent.d_type == UVWASI_FILETYPE_REGULAR_FILE);
86 name = &buf[UVWASI_SERDES_SIZE_dirent_t];
87 assert(strcmp(name, "test_file_") == 0);
88
89 /* Verify uvwasi_fd_readdir() happy path. */
90 memset(buf, 0, buf_size);
91 buf_used = 0;
92 cookie = UVWASI_DIRCOOKIE_START;
93 err = uvwasi_fd_readdir(&uvwasi, 3, &buf, buf_size, cookie, &buf_used);
94 assert(err == 0);
95 assert(buf_used == 2 * (UVWASI_SERDES_SIZE_dirent_t + 11));
96 uvwasi_serdes_read_dirent_t(buf, 0, &dirent);
97 assert(dirent.d_ino == 0);
98 assert(dirent.d_namlen == 11);
99 assert(dirent.d_type == UVWASI_FILETYPE_REGULAR_FILE);
100 name = &buf[UVWASI_SERDES_SIZE_dirent_t];
101 assert(strncmp(name, "test_file_1", 11) == 0 ||
102 strncmp(name, "test_file_2", 11) == 0);
103 uvwasi_serdes_read_dirent_t(buf, UVWASI_SERDES_SIZE_dirent_t + 11, &dirent);
104 assert(dirent.d_ino == 0);
105 assert(dirent.d_namlen == 11);
106 assert(dirent.d_type == UVWASI_FILETYPE_REGULAR_FILE);
107 name = &buf[(2 * UVWASI_SERDES_SIZE_dirent_t) + 11];
108 assert(strncmp(name, "test_file_1", 11) == 0 ||
109 strncmp(name, "test_file_2", 11) == 0);
110
111 uvwasi_destroy(&uvwasi);
112 free(init_options.preopens);
113 #endif /* !defined(_WIN32) && !defined(__ANDROID__) */
114 return 0;
115 }
116