Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #include "vtypes_internal.h" 00009 00010 #include "vfsnode.h" 00011 #include "vexception.h" 00012 00013 // This is a useful place to put a breakpoint when things aren't going as planned. 00014 static void _debugCheck(bool success) { 00015 if (! success) { 00016 VSystemError e; 00017 } 00018 } 00019 00020 // static 00021 int VFileSystem::mkdir(const VString& path, mode_t mode) { 00022 int result = 0; 00023 bool done = false; 00024 00025 while (! done) { 00026 result = VPlatformAPI::mkdir(path, mode); 00027 00028 if ((result == 0) || (errno != EINTR)) 00029 done = true; 00030 } 00031 00032 /* 00033 If two threads are competing to create the same directory, even if they 00034 both check for its existence, they might end up trying to create it at 00035 the same time -- one of them will get result -1 with errno == EEXIST. 00036 The best thing for our interface is to have mkdir succeed if the directory 00037 already exists. 00038 */ 00039 00040 if ((result == -1) && (errno == EEXIST)) { 00041 // Call stat to determine whether the existent node is a directory. 00042 // If it is, then we "succeeded" in creating it. 00043 VFSNode node(path); 00044 if (node.isDirectory()) 00045 result = 0; 00046 } 00047 00048 _debugCheck(result == 0); 00049 00050 return result; 00051 } 00052 00053 // static 00054 int VFileSystem::rename(const VString& oldName, const VString& newName) { 00055 int result = 0; 00056 bool done = false; 00057 00058 while (! done) { 00059 result = VPlatformAPI::rename(oldName, newName); 00060 00061 if ((result == 0) || (errno != EINTR)) 00062 done = true; 00063 } 00064 00065 _debugCheck(result == 0); 00066 00067 return result; 00068 } 00069 00070 // static 00071 int VFileSystem::stat(const VString& path, struct stat* buf) { 00072 int result = 0; 00073 bool done = false; 00074 00075 while (! done) { 00076 result = VPlatformAPI::stat(path, buf); 00077 00078 if ((result == 0) || (errno != EINTR)) 00079 done = true; 00080 } 00081 00082 _debugCheck(result == 0); 00083 00084 return result; 00085 } 00086 00087 // static 00088 int VFileSystem::unlink(const VString& path) { 00089 int result = 0; 00090 bool done = false; 00091 00092 while (! done) { 00093 result = VPlatformAPI::unlink(path); 00094 00095 if ((result == 0) || (errno != EINTR)) 00096 done = true; 00097 } 00098 00099 _debugCheck(result == 0); 00100 00101 return result; 00102 } 00103 00104 // static 00105 int VFileSystem::rmdir(const VString& path) { 00106 int result = 0; 00107 bool done = false; 00108 00109 while (! done) { 00110 result = VPlatformAPI::rmdir(path); 00111 00112 if ((result == 0) || (errno != EINTR)) 00113 done = true; 00114 } 00115 00116 _debugCheck(result == 0); 00117 00118 return result; 00119 } 00120 00121 // static 00122 int VFileSystem::open(const VString& path, int flags) { 00123 if (path.isEmpty()) 00124 return -1; 00125 00126 int fd = -1; 00127 bool done = false; 00128 00129 while (! done) { 00130 if (flags == WRITE_CREATE_MODE) 00131 fd = VPlatformAPI::open(path, WRITE_CREATE_MODE, OPEN_CREATE_PERMISSIONS); 00132 else 00133 fd = VPlatformAPI::open(path, flags, 0); 00134 00135 if ((fd != -1) || (errno != EINTR)) 00136 done = true; 00137 } 00138 00139 _debugCheck(fd != -1); 00140 00141 return fd; 00142 } 00143 00144 // static 00145 ssize_t VFileSystem::read(int fd, void* buffer, size_t numBytes) { 00146 ssize_t result = 0; 00147 bool done = false; 00148 00149 while (! done) { 00150 result = vault::read(fd, buffer, numBytes); 00151 00152 if ((result != (ssize_t) - 1) || (errno != EINTR)) 00153 done = true; 00154 } 00155 00156 _debugCheck(result != -1); 00157 00158 return result; 00159 } 00160 00161 // static 00162 ssize_t VFileSystem::write(int fd, const void* buffer, size_t numBytes) { 00163 ssize_t result = 0; 00164 bool done = false; 00165 00166 while (! done) { 00167 result = vault::write(fd, buffer, numBytes); 00168 00169 if ((result != (ssize_t) - 1) || (errno != EINTR)) 00170 done = true; 00171 } 00172 00173 _debugCheck(result != -1); 00174 00175 return result; 00176 } 00177 00178 // static 00179 off_t VFileSystem::lseek(int fd, off_t offset, int whence) { 00180 off_t result = 0; 00181 bool done = false; 00182 00183 while (! done) { 00184 result = vault::lseek(fd, offset, whence); 00185 00186 if ((result != (off_t) - 1) || (errno != EINTR)) 00187 done = true; 00188 } 00189 00190 _debugCheck(result != (off_t) - 1); 00191 00192 return result; 00193 } 00194 00195 // static 00196 int VFileSystem::close(int fd) { 00197 int result = 0; 00198 bool done = false; 00199 00200 while (! done) { 00201 result = vault::close(fd); 00202 00203 if ((result == 0) || (errno != EINTR)) 00204 done = true; 00205 } 00206 00207 _debugCheck(result != -1); 00208 00209 return result; 00210 } 00211 00212 // static 00213 FILE* VFileSystem::fopen(const VString& nativePath, const char* mode) { 00214 if (nativePath.isEmpty()) 00215 return NULL; 00216 00217 FILE* f = NULL; 00218 bool done = false; 00219 00220 while (! done) { 00221 f = VPlatformAPI::fopen(nativePath, mode); 00222 00223 if ((f != NULL) || (errno != EINTR)) { 00224 done = true; 00225 } 00226 } 00227 00228 _debugCheck(f != NULL); 00229 00230 return f; 00231 } 00232 00233 // static 00234 int VFileSystem::fclose(FILE* f) { 00235 if (f == NULL) 00236 return EOF; 00237 00238 int result = 0; 00239 bool done = false; 00240 00241 while (! done) { 00242 result = ::fclose(f); 00243 00244 if ((result == 0) || (errno != EINTR)) { 00245 done = true; 00246 } 00247 } 00248 00249 _debugCheck(result == 0); 00250 00251 return result; 00252 } 00253 00254 // static 00255 size_t VFileSystem::fread(void* buffer, size_t size, size_t numItems, FILE* f) { 00256 if ((buffer == NULL) || (f == NULL)) { 00257 return 0; 00258 } 00259 00260 size_t result = 0; 00261 bool done = false; 00262 00263 while (! done) { 00264 result = ::fread(buffer, size, numItems, f); 00265 00266 if ((result != numItems) && (ferror(f) != 0) && (errno == EINTR)) { 00267 done = false; 00268 } else { 00269 done = true; 00270 } 00271 } 00272 00273 _debugCheck(result == numItems); 00274 00275 return result; 00276 } 00277 00278 // static 00279 size_t VFileSystem::fwrite(const void* buffer, size_t size, size_t numItems, FILE* f) { 00280 size_t result = 0L; 00281 bool done = false; 00282 00283 if ((buffer == NULL) || (f == NULL)) { 00284 return 0L; 00285 } 00286 00287 while (! done) { 00288 result = ::fwrite(buffer, size, numItems, f); 00289 00290 if ((result != numItems) && (ferror(f) != 0) && (errno == EINTR)) { 00291 done = false; 00292 } else { 00293 done = true; 00294 } 00295 } 00296 00297 _debugCheck(result == numItems); 00298 00299 return result; 00300 } 00301 00302 // static 00303 int VFileSystem::fseek(FILE* f, long int offset, int whence) { 00304 int result = 0; 00305 bool done = false; 00306 00307 if (f == NULL) { 00308 return EOF; 00309 } 00310 00311 while (! done) { 00312 result = ::fseek(f, offset, whence); 00313 00314 if ((result != -1) || (errno != EINTR)) { 00315 done = true; 00316 } 00317 } 00318 00319 _debugCheck(result == 0); 00320 00321 return result; 00322 } 00323 00324 // static 00325 int VFileSystem::fflush(FILE* f) { 00326 int result = 0; 00327 bool done = false; 00328 00329 if (f == NULL) { 00330 return EOF; 00331 } 00332 00333 while (! done) { 00334 result = ::fflush(f); 00335 00336 if ((result == 0) || (errno != EINTR)) { 00337 done = true; 00338 } 00339 } 00340 _debugCheck(result == 0); 00341 00342 return result; 00343 } 00344 00345 // static 00346 long int VFileSystem::ftell(FILE* f) { 00347 long int result = 0; 00348 bool done = false; 00349 00350 if (f == NULL) { 00351 return 0; 00352 } 00353 00354 while (! done) { 00355 result = ::ftell(f); 00356 00357 if ((result >= 0) || (errno != EINTR)) { 00358 done = true; 00359 } 00360 } 00361 00362 _debugCheck(result != -1); 00363 00364 return result; 00365 }