test-fs-readdir.c
Go to the documentation of this file.
1 /* Copyright libuv project contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "task.h"
24 #include <fcntl.h>
25 #include <string.h>
26 
30 
31 static uv_dirent_t dirents[1];
32 
35 
36 static void cleanup_test_files(void) {
37  uv_fs_t req;
38 
39  uv_fs_unlink(NULL, &req, "test_dir/file1", NULL);
41  uv_fs_unlink(NULL, &req, "test_dir/file2", NULL);
43  uv_fs_rmdir(NULL, &req, "test_dir/test_subdir", NULL);
45  uv_fs_rmdir(NULL, &req, "test_dir", NULL);
47 }
48 
49 static void empty_closedir_cb(uv_fs_t* req) {
50  ASSERT(req == &closedir_req);
51  ASSERT(req->fs_type == UV_FS_CLOSEDIR);
52  ASSERT(req->result == 0);
55 }
56 
57 static void empty_readdir_cb(uv_fs_t* req) {
58  uv_dir_t* dir;
59  int r;
60 
61  ASSERT(req == &readdir_req);
62  ASSERT(req->fs_type == UV_FS_READDIR);
63  ASSERT(req->result == 0);
64  dir = req->ptr;
67  &closedir_req,
68  dir,
70  ASSERT(r == 0);
71 }
72 
73 static void empty_opendir_cb(uv_fs_t* req) {
74  uv_dir_t* dir;
75  int r;
76 
77  ASSERT(req == &opendir_req);
78  ASSERT(req->fs_type == UV_FS_OPENDIR);
79  ASSERT(req->result == 0);
80  ASSERT(req->ptr != NULL);
81  dir = req->ptr;
82  dir->dirents = dirents;
83  dir->nentries = ARRAY_SIZE(dirents);
85  &readdir_req,
86  dir,
88  ASSERT(r == 0);
91 }
92 
93 /*
94  * This test makes sure that both synchronous and asynchronous flavors
95  * of the uv_fs_opendir() -> uv_fs_readdir() -> uv_fs_closedir() sequence work
96  * as expected when processing an empty directory.
97  */
98 TEST_IMPL(fs_readdir_empty_dir) {
99  const char* path;
102  int r;
103  int nb_entries_read;
104  uv_dir_t* dir;
105 
106  path = "./empty_dir/";
107  uv_fs_mkdir(uv_default_loop(), &mkdir_req, path, 0777, NULL);
109 
110  /* Fill the req to ensure that required fields are cleaned up. */
111  memset(&opendir_req, 0xdb, sizeof(opendir_req));
112 
113  /* Testing the synchronous flavor. */
115  &opendir_req,
116  path,
117  NULL);
118  ASSERT(r == 0);
120  ASSERT(opendir_req.result == 0);
121  ASSERT(opendir_req.ptr != NULL);
122  dir = opendir_req.ptr;
124 
125  /* Fill the req to ensure that required fields are cleaned up. */
126  memset(&readdir_req, 0xdb, sizeof(readdir_req));
127  dir->dirents = dirents;
128  dir->nentries = ARRAY_SIZE(dirents);
129  nb_entries_read = uv_fs_readdir(uv_default_loop(),
130  &readdir_req,
131  dir,
132  NULL);
133  ASSERT(nb_entries_read == 0);
135 
136  /* Fill the req to ensure that required fields are cleaned up. */
137  memset(&closedir_req, 0xdb, sizeof(closedir_req));
139  ASSERT(closedir_req.result == 0);
141 
142  /* Testing the asynchronous flavor. */
143 
144  /* Fill the req to ensure that required fields are cleaned up. */
145  memset(&opendir_req, 0xdb, sizeof(opendir_req));
146  memset(&readdir_req, 0xdb, sizeof(readdir_req));
147  memset(&closedir_req, 0xdb, sizeof(closedir_req));
148 
150  ASSERT(r == 0);
154  ASSERT(r == 0);
160  return 0;
161 }
162 
163 /*
164  * This test makes sure that reading a non-existing directory with
165  * uv_fs_{open,read}_dir() returns proper error codes.
166  */
167 
169 
171  ASSERT(req == &opendir_req);
172  ASSERT(req->fs_type == UV_FS_OPENDIR);
173  ASSERT(req->result == UV_ENOENT);
174  ASSERT(req->ptr == NULL);
175 
178 }
179 
180 TEST_IMPL(fs_readdir_non_existing_dir) {
181  const char* path;
182  int r;
183 
184  path = "./non-existing-dir/";
185 
186  /* Fill the req to ensure that required fields are cleaned up. */
187  memset(&opendir_req, 0xdb, sizeof(opendir_req));
188 
189  /* Testing the synchronous flavor. */
191  ASSERT(r == UV_ENOENT);
193  ASSERT(opendir_req.result == UV_ENOENT);
194  ASSERT(opendir_req.ptr == NULL);
196 
197  /* Fill the req to ensure that required fields are cleaned up. */
198  memset(&opendir_req, 0xdb, sizeof(opendir_req));
199 
200  /* Testing the async flavor. */
202  &opendir_req,
203  path,
205  ASSERT(r == 0);
208  ASSERT(r == 0);
210 
212  return 0;
213 }
214 
215 /*
216  * This test makes sure that reading a file as a directory reports correct
217  * error codes.
218  */
219 
221 
222 static void file_opendir_cb(uv_fs_t* req) {
223  ASSERT(req == &opendir_req);
224  ASSERT(req->fs_type == UV_FS_OPENDIR);
225  ASSERT(req->result == UV_ENOTDIR);
226  ASSERT(req->ptr == NULL);
227 
230 }
231 
232 TEST_IMPL(fs_readdir_file) {
233  const char* path;
234  int r;
235 
236  path = "test/fixtures/empty_file";
237 
238  /* Fill the req to ensure that required fields are cleaned up. */
239  memset(&opendir_req, 0xdb, sizeof(opendir_req));
240 
241  /* Testing the synchronous flavor. */
243 
244  ASSERT(r == UV_ENOTDIR);
246  ASSERT(opendir_req.result == UV_ENOTDIR);
247  ASSERT(opendir_req.ptr == NULL);
248 
250 
251  /* Fill the req to ensure that required fields are cleaned up. */
252  memset(&opendir_req, 0xdb, sizeof(opendir_req));
253 
254  /* Testing the async flavor. */
256  ASSERT(r == 0);
259  ASSERT(r == 0);
262  return 0;
263 }
264 
265 /*
266  * This test makes sure that reading a non-empty directory with
267  * uv_fs_{open,read}_dir() returns proper directory entries, including the
268  * correct entry types.
269  */
270 
274 
276  ASSERT(req == &closedir_req);
277  ASSERT(req->result == 0);
280 }
281 
283  uv_dir_t* dir;
284 
285  ASSERT(req == &readdir_req);
286  ASSERT(req->fs_type == UV_FS_READDIR);
287  dir = req->ptr;
288 
289  if (req->result == 0) {
293  &closedir_req,
294  dir,
296  } else {
297  ASSERT(req->result == 1);
298  ASSERT(dir->dirents == dirents);
299  ASSERT(strcmp(dirents[0].name, "file1") == 0 ||
300  strcmp(dirents[0].name, "file2") == 0 ||
301  strcmp(dirents[0].name, "test_subdir") == 0);
302 #ifdef HAVE_DIRENT_TYPES
303  if (!strcmp(dirents[0].name, "test_subdir"))
305  else
307 #else
309 #endif /* HAVE_DIRENT_TYPES */
310 
313  dir->dirents = dirents;
314  dir->nentries = ARRAY_SIZE(dirents);
316  &readdir_req,
317  dir,
319  }
320 }
321 
323  uv_dir_t* dir;
324  int r;
325 
326  ASSERT(req == &opendir_req);
327  ASSERT(req->fs_type == UV_FS_OPENDIR);
328  ASSERT(req->result == 0);
329  ASSERT(req->ptr != NULL);
330 
331  dir = req->ptr;
332  dir->dirents = dirents;
333  dir->nentries = ARRAY_SIZE(dirents);
334 
336  &readdir_req,
337  dir,
339  ASSERT(r == 0);
342 }
343 
344 TEST_IMPL(fs_readdir_non_empty_dir) {
345  size_t entries_count;
348  uv_fs_t create_req;
350  uv_dir_t* dir;
351  int r;
352 
354 
355  r = uv_fs_mkdir(uv_default_loop(), &mkdir_req, "test_dir", 0755, NULL);
356  ASSERT(r == 0);
357 
358  /* Create two files synchronously. */
360  &create_req,
361  "test_dir/file1",
362  O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR,
363  NULL);
364  ASSERT(r >= 0);
365  uv_fs_req_cleanup(&create_req);
367  &close_req,
368  create_req.result,
369  NULL);
370  ASSERT(r == 0);
372 
374  &create_req,
375  "test_dir/file2",
376  O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR,
377  NULL);
378  ASSERT(r >= 0);
379  uv_fs_req_cleanup(&create_req);
381  &close_req,
382  create_req.result,
383  NULL);
384  ASSERT(r == 0);
386 
388  &mkdir_req,
389  "test_dir/test_subdir",
390  0755,
391  NULL);
392  ASSERT(r == 0);
394 
395  /* Fill the req to ensure that required fields are cleaned up. */
396  memset(&opendir_req, 0xdb, sizeof(opendir_req));
397 
398  /* Testing the synchronous flavor. */
399  r = uv_fs_opendir(uv_default_loop(), &opendir_req, "test_dir", NULL);
400  ASSERT(r == 0);
402  ASSERT(opendir_req.result == 0);
403  ASSERT(opendir_req.ptr != NULL);
404 
405  entries_count = 0;
406  dir = opendir_req.ptr;
407  dir->dirents = dirents;
408  dir->nentries = ARRAY_SIZE(dirents);
410 
412  &readdir_req,
413  dir,
414  NULL) != 0) {
415  ASSERT(strcmp(dirents[0].name, "file1") == 0 ||
416  strcmp(dirents[0].name, "file2") == 0 ||
417  strcmp(dirents[0].name, "test_subdir") == 0);
418 #ifdef HAVE_DIRENT_TYPES
419  if (!strcmp(dirents[0].name, "test_subdir"))
421  else
423 #else
425 #endif /* HAVE_DIRENT_TYPES */
427  ++entries_count;
428  }
429 
430  ASSERT(entries_count == 3);
432 
433  /* Fill the req to ensure that required fields are cleaned up. */
434  memset(&closedir_req, 0xdb, sizeof(closedir_req));
436  ASSERT(closedir_req.result == 0);
438 
439  /* Testing the asynchronous flavor. */
440 
441  /* Fill the req to ensure that required fields are cleaned up. */
442  memset(&opendir_req, 0xdb, sizeof(opendir_req));
443 
445  &opendir_req,
446  "test_dir",
448  ASSERT(r == 0);
452  ASSERT(r == 0);
455 
456  uv_fs_rmdir(uv_default_loop(), &rmdir_req, "test_subdir", NULL);
458 
461  return 0;
462  }
uv_fs_rmdir
UV_EXTERN int uv_fs_rmdir(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: unix/fs.c:1931
non_empty_closedir_cb
static void non_empty_closedir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:275
non_empty_closedir_cb_count
static int non_empty_closedir_cb_count
Definition: test-fs-readdir.c:273
file_opendir_cb
static void file_opendir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:222
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
uv_fs_open
UV_EXTERN int uv_fs_open(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, int mode, uv_fs_cb cb)
Definition: unix/fs.c:1812
task.h
closedir_req
static uv_fs_t closedir_req
Definition: test-fs-readdir.c:29
memset
return memset(p, 0, total)
UV_DIRENT_FILE
@ UV_DIRENT_FILE
Definition: uv.h:1130
uv_dir_s
Definition: uv.h:1286
empty_opendir_cb_count
static int empty_opendir_cb_count
Definition: test-fs-readdir.c:33
string.h
non_empty_opendir_cb_count
static int non_empty_opendir_cb_count
Definition: test-fs-readdir.c:271
uv_fs_readdir
UV_EXTERN int uv_fs_readdir(uv_loop_t *loop, uv_fs_t *req, uv_dir_t *dir, uv_fs_cb cb)
Definition: unix/fs.c:1874
non_empty_readdir_cb
static void non_empty_readdir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:282
ASSERT
#define ASSERT(expr)
Definition: task.h:102
TEST_IMPL
TEST_IMPL(fs_readdir_empty_dir)
Definition: test-fs-readdir.c:98
setup.name
name
Definition: setup.py:542
check_documentation.path
path
Definition: check_documentation.py:57
rmdir_req
static uv_fs_t rmdir_req
Definition: test-fs.c:115
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
readdir_req
static uv_fs_t readdir_req
Definition: test-fs-readdir.c:28
uv_fs_s::result
ssize_t result
Definition: uv.h:1299
uv_fs_s
Definition: uv.h:1294
uv_fs_mkdir
UV_EXTERN int uv_fs_mkdir(uv_loop_t *loop, uv_fs_t *req, const char *path, int mode, uv_fs_cb cb)
Definition: unix/fs.c:1776
dirents
static uv_dirent_t dirents[1]
Definition: test-fs-readdir.c:31
uv_fs_unlink
UV_EXTERN int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: unix/fs.c:1974
empty_readdir_cb
static void empty_readdir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:57
opendir_req
static uv_fs_t opendir_req
Definition: test-fs-readdir.c:27
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
req
static uv_connect_t req
Definition: test-connection-fail.c:30
UV_FS_READDIR
@ UV_FS_READDIR
Definition: uv.h:1279
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
close_req
static uv_fs_t close_req
Definition: test-fs.c:108
empty_closedir_cb_count
static int empty_closedir_cb_count
Definition: test-fs-readdir.c:34
uv_dir_s::nentries
size_t nentries
Definition: uv.h:1288
uv_fs_close
UV_EXTERN int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb)
Definition: unix/fs.c:1651
UV_FS_CLOSEDIR
@ UV_FS_CLOSEDIR
Definition: uv.h:1280
non_empty_readdir_cb_count
static int non_empty_readdir_cb_count
Definition: test-fs-readdir.c:272
file_opendir_cb_count
static int file_opendir_cb_count
Definition: test-fs-readdir.c:220
uv.h
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
uv_dirent_s
Definition: uv.h:1139
UV_FS_OPENDIR
@ UV_FS_OPENDIR
Definition: uv.h:1278
mkdir_req
static uv_fs_t mkdir_req
Definition: test-fs.c:109
uv_fs_opendir
UV_EXTERN int uv_fs_opendir(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)
Definition: unix/fs.c:1865
cleanup_test_files
static void cleanup_test_files(void)
Definition: test-fs-readdir.c:36
fix_build_deps.r
r
Definition: fix_build_deps.py:491
empty_opendir_cb
static void empty_opendir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:73
uv_fs_closedir
UV_EXTERN int uv_fs_closedir(uv_loop_t *loop, uv_fs_t *req, uv_dir_t *dir, uv_fs_cb cb)
Definition: unix/fs.c:1887
non_existing_opendir_cb_count
static int non_existing_opendir_cb_count
Definition: test-fs-readdir.c:168
non_empty_opendir_cb
static void non_empty_opendir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:322
uv_fs_req_cleanup
UV_EXTERN void uv_fs_req_cleanup(uv_fs_t *req)
Definition: unix/fs.c:2024
uv_fs_s::fs_type
UV_REQ_FIELDS uv_fs_type fs_type
Definition: uv.h:1296
empty_closedir_cb
static void empty_closedir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:49
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
uv_fs_s::ptr
void * ptr
Definition: uv.h:1300
UV_DIRENT_UNKNOWN
@ UV_DIRENT_UNKNOWN
Definition: uv.h:1129
non_existing_opendir_cb
static void non_existing_opendir_cb(uv_fs_t *req)
Definition: test-fs-readdir.c:170
UV_DIRENT_DIR
@ UV_DIRENT_DIR
Definition: uv.h:1131
uv_dir_s::dirents
uv_dirent_t * dirents
Definition: uv.h:1287


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:26