1 /*
2 * Copyright (c) 2018 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #undef _POSIX_C_SOURCE
8 #define _POSIX_C_SOURCE 200809L
9
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <zephyr/posix/unistd.h>
13 #include <zephyr/posix/dirent.h>
14 #include "test_fs.h"
15
16 extern int test_file_write(void);
17 extern int test_file_close(void);
18 extern int file;
19
test_mkdir(void)20 static int test_mkdir(void)
21 {
22 int res;
23
24 TC_PRINT("\nmkdir tests:\n");
25
26 /* Verify fs_mkdir() */
27 res = mkdir(TEST_DIR, S_IRWXG);
28 if (res) {
29 TC_PRINT("Error creating dir[%d]\n", res);
30 return res;
31 }
32
33 res = open(TEST_DIR_FILE, O_CREAT | O_RDWR, 0770);
34
35 if (res < 0) {
36 TC_PRINT("Failed opening file [%d]\n", res);
37 return res;
38 }
39 file = res;
40
41 res = test_file_write();
42 if (res) {
43 return res;
44 }
45
46 res = close(file);
47 if (res) {
48 TC_PRINT("Error closing file [%d]\n", res);
49 return res;
50 }
51
52 TC_PRINT("Created dir %s!\n", TEST_DIR);
53
54 return res;
55 }
56
readdir_wrap(DIR * dirp,bool thread_safe)57 static struct dirent *readdir_wrap(DIR *dirp, bool thread_safe)
58 {
59 if (thread_safe) {
60 struct dirent entry;
61 struct dirent *result = NULL;
62
63 zassert_ok(readdir_r(dirp, &entry, &result));
64
65 return result;
66 } else {
67 return readdir(dirp);
68 }
69 }
70
test_lsdir(const char * path,bool thread_safe)71 static int test_lsdir(const char *path, bool thread_safe)
72 {
73 DIR *dirp;
74 int res = 0;
75 struct dirent *entry;
76
77 TC_PRINT("\nreaddir test:\n");
78
79 /* Verify fs_opendir() */
80 dirp = opendir(path);
81 if (dirp == NULL) {
82 TC_PRINT("Error opening dir %s\n", path);
83 return -EIO;
84 }
85
86 TC_PRINT("\nListing dir %s:\n", path);
87 /* Verify fs_readdir() */
88 errno = 0;
89 while ((entry = readdir_wrap(dirp, thread_safe)) != NULL) {
90 if (entry->d_name[0] == 0) {
91 res = -EIO;
92 break;
93 }
94
95 TC_PRINT("[FILE] %s\n", entry->d_name);
96 }
97
98 if (errno) {
99 res = -EIO;
100 }
101
102 /* Verify fs_closedir() */
103 closedir(dirp);
104
105 return res;
106 }
107
after_fn(void * unused)108 static void after_fn(void *unused)
109 {
110 ARG_UNUSED(unused);
111
112 unlink(TEST_DIR_FILE);
113 unlink(TEST_DIR);
114 }
115
116 /* FIXME: restructure tests as per #46897 */
117 ZTEST_SUITE(posix_fs_dir_test, NULL, test_mount, NULL, after_fn,
118 test_unmount);
119
120 /**
121 * @brief Test for POSIX mkdir API
122 *
123 * @details Test creates a new directory through POSIX
124 * mkdir API and open a new file under the directory and
125 * writes some data into the file.
126 */
ZTEST(posix_fs_dir_test,test_fs_mkdir)127 ZTEST(posix_fs_dir_test, test_fs_mkdir)
128 {
129 /* FIXME: restructure tests as per #46897 */
130 zassert_true(test_mkdir() == TC_PASS);
131 }
132
133 /**
134 * @brief Test for POSIX opendir, readdir and closedir API
135 *
136 * @details Test opens an existing directory through POSIX
137 * opendir API, reads the contents of the directory through
138 * readdir API and closes it through closedir API.
139 */
ZTEST(posix_fs_dir_test,test_fs_readdir)140 ZTEST(posix_fs_dir_test, test_fs_readdir)
141 {
142 /* FIXME: restructure tests as per #46897 */
143 zassert_true(test_mkdir() == TC_PASS);
144 zassert_true(test_lsdir(TEST_DIR, false) == TC_PASS);
145 }
146
147 /**
148 * Same test as `test_fs_readdir`, but use thread-safe `readdir_r()` function
149 */
ZTEST(posix_fs_dir_test,test_fs_readdir_threadsafe)150 ZTEST(posix_fs_dir_test, test_fs_readdir_threadsafe)
151 {
152 /* FIXME: restructure tests as per #46897 */
153 zassert_true(test_mkdir() == TC_PASS);
154 zassert_true(test_lsdir(TEST_DIR, true) == TC_PASS);
155 }
156
157 /**
158 * @brief Test for POSIX rmdir API
159 *
160 * @details Test creates a new directory through POSIX
161 * mkdir API and remove directory using rmdir.
162 */
ZTEST(posix_fs_dir_test,test_fs_rmdir)163 ZTEST(posix_fs_dir_test, test_fs_rmdir)
164 {
165 #define IRWXG 0070
166 /* Create and remove empty directory */
167 zassert_ok(mkdir(TEST_DIR, IRWXG), "Error creating dir: %d", errno);
168 zassert_ok(rmdir(TEST_DIR), "Error removing dir: %d\n", errno);
169
170 /* Create directory and open a file in the directory
171 * now removing the directory will fail, test will
172 * fail in removal of non empty directory
173 */
174 zassert_ok(mkdir(TEST_DIR, IRWXG), "Error creating dir: %d", errno);
175 zassert_not_equal(open(TEST_DIR_FILE, O_CREAT | O_RDWR), -1,
176 "Error creating file: %d", errno);
177 zassert_not_ok(rmdir(TEST_DIR), "Error Non empty dir removed");
178 zassert_not_ok(rmdir(""), "Error Invalid path removed");
179 zassert_not_ok(rmdir(NULL), "Error Invalid path removed");
180 zassert_not_ok(rmdir("TEST_DIR."), "Error Invalid path removed");
181 zassert_not_ok(rmdir(TEST_FILE), "Error file removed");
182 }
183