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