1313// limitations under the License.
1414
1515#include " vfs_api.h"
16+ #include < errno.h>
17+ #include < stdlib.h>
18+ #include < string.h>
1619
1720using namespace fs ;
1821
@@ -38,8 +41,47 @@ FileImplPtr VFSImpl::open(const char *fpath, const char *mode, const bool create
3841 strcpy (temp, _mountpoint);
3942 strcat (temp, fpath);
4043
44+ // Try to open as file first - let the file operation handle errors
45+ if (mode && mode[0 ] != ' r' ) {
46+ // For write modes, attempt to create directories if needed
47+ if (create) {
48+ char *token;
49+ char *folder = (char *)malloc (strlen (fpath) + 1 );
50+
51+ int start_index = 0 ;
52+ int end_index = 0 ;
53+
54+ token = strchr (fpath + 1 , ' /' );
55+ end_index = (token - fpath);
56+
57+ while (token != NULL ) {
58+ memcpy (folder, fpath + start_index, end_index - start_index);
59+ folder[end_index - start_index] = ' \0 ' ;
60+
61+ if (!VFSImpl::mkdir (folder)) {
62+ log_e (" Creating folder: %s failed!" , folder);
63+ free (folder);
64+ free (temp);
65+ return FileImplPtr ();
66+ }
67+
68+ token = strchr (token + 1 , ' /' );
69+ if (token != NULL ) {
70+ end_index = (token - fpath);
71+ memset (folder, 0 , strlen (folder));
72+ }
73+ }
74+
75+ free (folder);
76+ }
77+
78+ // Try to open the file directly - let fopen handle errors
79+ free (temp);
80+ return std::make_shared<VFSFileImpl>(this , fpath, mode);
81+ }
82+
83+ // For read mode, try to open as file first
4184 struct stat st;
42- // file found
4385 if (!stat (temp, &st)) {
4486 free (temp);
4587 if (S_ISREG (st.st_mode ) || S_ISDIR (st.st_mode )) {
@@ -49,54 +91,15 @@ FileImplPtr VFSImpl::open(const char *fpath, const char *mode, const bool create
4991 return FileImplPtr ();
5092 }
5193
52- // try to open this as directory (might be mount point)
94+ // Try to open as directory (might be mount point)
5395 DIR *d = opendir (temp);
5496 if (d) {
5597 closedir (d);
5698 free (temp);
5799 return std::make_shared<VFSFileImpl>(this , fpath, mode);
58100 }
59101
60- // file not found but mode permits file creation without folder creation
61- if ((mode && mode[0 ] != ' r' ) && (!create)) {
62- free (temp);
63- return std::make_shared<VFSFileImpl>(this , fpath, mode);
64- }
65-
66- // //file not found but mode permits file creation and folder creation
67- if ((mode && mode[0 ] != ' r' ) && create) {
68-
69- char *token;
70- char *folder = (char *)malloc (strlen (fpath) + 1 );
71-
72- int start_index = 0 ;
73- int end_index = 0 ;
74-
75- token = strchr (fpath + 1 , ' /' );
76- end_index = (token - fpath);
77-
78- while (token != NULL ) {
79- memcpy (folder, fpath + start_index, end_index - start_index);
80- folder[end_index - start_index] = ' \0 ' ;
81-
82- if (!VFSImpl::mkdir (folder)) {
83- log_e (" Creating folder: %s failed!" , folder);
84- return FileImplPtr ();
85- }
86-
87- token = strchr (token + 1 , ' /' );
88- if (token != NULL ) {
89- end_index = (token - fpath);
90- memset (folder, 0 , strlen (folder));
91- }
92- }
93-
94- free (folder);
95- free (temp);
96- return std::make_shared<VFSFileImpl>(this , fpath, mode);
97- }
98-
99- log_e (" %s does not exist, no permits for creation" , temp);
102+ // File not found and read mode - return empty
100103 free (temp);
101104 return FileImplPtr ();
102105}
@@ -125,10 +128,7 @@ bool VFSImpl::rename(const char *pathFrom, const char *pathTo) {
125128 log_e (" bad arguments" );
126129 return false ;
127130 }
128- if (!exists (pathFrom)) {
129- log_e (" %s does not exists" , pathFrom);
130- return false ;
131- }
131+
132132 size_t mountpointLen = strlen (_mountpoint);
133133 char *temp1 = (char *)malloc (strlen (pathFrom) + mountpointLen + 1 );
134134 if (!temp1) {
@@ -148,6 +148,7 @@ bool VFSImpl::rename(const char *pathFrom, const char *pathTo) {
148148 strcpy (temp2, _mountpoint);
149149 strcat (temp2, pathTo);
150150
151+ // Let rename() handle the error if source doesn't exist
151152 auto rc = ::rename (temp1, temp2);
152153 free (temp1);
153154 free (temp2);
@@ -165,16 +166,6 @@ bool VFSImpl::remove(const char *fpath) {
165166 return false ;
166167 }
167168
168- VFSFileImpl f (this , fpath, " r" );
169- if (!f || f.isDirectory ()) {
170- if (f) {
171- f.close ();
172- }
173- log_e (" %s does not exists or is directory" , fpath);
174- return false ;
175- }
176- f.close ();
177-
178169 char *temp = (char *)malloc (strlen (fpath) + strlen (_mountpoint) + 1 );
179170 if (!temp) {
180171 log_e (" malloc failed" );
@@ -184,6 +175,7 @@ bool VFSImpl::remove(const char *fpath) {
184175 strcpy (temp, _mountpoint);
185176 strcat (temp, fpath);
186177
178+ // Let unlink() handle the error if file doesn't exist
187179 auto rc = unlink (temp);
188180 free (temp);
189181 return rc == 0 ;
@@ -195,17 +187,6 @@ bool VFSImpl::mkdir(const char *fpath) {
195187 return false ;
196188 }
197189
198- VFSFileImpl f (this , fpath, " r" );
199- if (f && f.isDirectory ()) {
200- f.close ();
201- // log_w("%s already exists", fpath);
202- return true ;
203- } else if (f) {
204- f.close ();
205- log_e (" %s is a file" , fpath);
206- return false ;
207- }
208-
209190 char *temp = (char *)malloc (strlen (fpath) + strlen (_mountpoint) + 1 );
210191 if (!temp) {
211192 log_e (" malloc failed" );
@@ -215,9 +196,15 @@ bool VFSImpl::mkdir(const char *fpath) {
215196 strcpy (temp, _mountpoint);
216197 strcat (temp, fpath);
217198
199+ // Let mkdir() handle the error if directory already exists
218200 auto rc = ::mkdir (temp, ACCESSPERMS);
219201 free (temp);
220- return rc == 0 ;
202+
203+ // EEXIST means directory already exists, which is fine
204+ if (rc == 0 || errno == EEXIST) {
205+ return true ;
206+ }
207+ return false ;
221208}
222209
223210bool VFSImpl::rmdir (const char *fpath) {
@@ -231,16 +218,6 @@ bool VFSImpl::rmdir(const char *fpath) {
231218 return false ;
232219 }
233220
234- VFSFileImpl f (this , fpath, " r" );
235- if (!f || !f.isDirectory ()) {
236- if (f) {
237- f.close ();
238- }
239- log_e (" %s does not exists or is a file" , fpath);
240- return false ;
241- }
242- f.close ();
243-
244221 char *temp = (char *)malloc (strlen (fpath) + strlen (_mountpoint) + 1 );
245222 if (!temp) {
246223 log_e (" malloc failed" );
@@ -250,6 +227,7 @@ bool VFSImpl::rmdir(const char *fpath) {
250227 strcpy (temp, _mountpoint);
251228 strcat (temp, fpath);
252229
230+ // Let rmdir() handle the error if directory doesn't exist
253231 auto rc = ::rmdir (temp);
254232 free (temp);
255233 return rc == 0 ;
@@ -271,8 +249,27 @@ VFSFileImpl::VFSFileImpl(VFSImpl *fs, const char *fpath, const char *mode) : _fs
271249 return ;
272250 }
273251
252+ // Try to open as file first
253+ _f = fopen (temp, mode);
254+ if (_f) {
255+ _isDirectory = false ;
256+ if (_stat.st_blksize == 0 ) {
257+ setvbuf (_f, NULL , _IOFBF, DEFAULT_FILE_BUFFER_SIZE);
258+ }
259+ free (temp);
260+ return ;
261+ }
262+
263+ // Try to open as directory
264+ _d = opendir (temp);
265+ if (_d) {
266+ _isDirectory = true ;
267+ free (temp);
268+ return ;
269+ }
270+
271+ // If neither worked, try to stat to determine type
274272 if (!stat (temp, &_stat)) {
275- // file found
276273 if (S_ISREG (_stat.st_mode )) {
277274 _isDirectory = false ;
278275 _f = fopen (temp, mode);
@@ -292,18 +289,8 @@ VFSFileImpl::VFSFileImpl(VFSImpl *fs, const char *fpath, const char *mode) : _fs
292289 log_e (" Unknown type 0x%08X for file %s" , ((_stat.st_mode ) & _IFMT), temp);
293290 }
294291 } else {
295- // file not found
296- if (!mode || mode[0 ] == ' r' ) {
297- // try to open as directory
298- _d = opendir (temp);
299- if (_d) {
300- _isDirectory = true ;
301- } else {
302- _isDirectory = false ;
303- // log_w("stat(%s) failed", temp);
304- }
305- } else {
306- // lets create this new file
292+ // File not found - this is normal for write modes
293+ if (mode && mode[0 ] != ' r' ) {
307294 _isDirectory = false ;
308295 _f = fopen (temp, mode);
309296 if (!_f) {
0 commit comments