FileSystemManx.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
  3. * Copyright (C) 2012 Sony Computer Entertainment Inc.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #include "config.h"
  30. #include "FileSystem.h"
  31. #include "NotImplemented.h"
  32. #include <dirent.h>
  33. #include <errno.h>
  34. #include <fcntl.h>
  35. #include <libgen.h>
  36. #include <stdio.h>
  37. #include <sys/stat.h>
  38. #include <sys/types.h>
  39. #include <unistd.h>
  40. #include <wtf/text/CString.h>
  41. #if OS(PS3)
  42. #include <fnmatch.h>
  43. #endif
  44. namespace WebCore {
  45. bool fileExists(const String& path)
  46. {
  47. if (path.isNull())
  48. return false;
  49. CString fsRep = fileSystemRepresentation(path);
  50. if (!fsRep.data() || fsRep.data()[0] == '\0')
  51. return false;
  52. struct stat fileInfo;
  53. // stat(...) returns 0 on successful stat'ing of the file, and non-zero in any case where the file doesn't exist or cannot be accessed
  54. return !stat(fsRep.data(), &fileInfo);
  55. }
  56. bool deleteFile(const String& path)
  57. {
  58. CString fsRep = fileSystemRepresentation(path);
  59. if (!fsRep.data() || fsRep.data()[0] == '\0')
  60. return false;
  61. // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
  62. return !unlink(fsRep.data());
  63. }
  64. PlatformFileHandle openFile(const String& path, FileOpenMode mode)
  65. {
  66. CString fsRep = fileSystemRepresentation(path);
  67. if (fsRep.isNull())
  68. return invalidPlatformFileHandle;
  69. int platformFlag = 0;
  70. if (mode == OpenForRead)
  71. platformFlag |= O_RDONLY;
  72. else if (mode == OpenForWrite)
  73. platformFlag |= (O_WRONLY | O_CREAT | O_TRUNC);
  74. return open(fsRep.data(), platformFlag, 0666);
  75. }
  76. void closeFile(PlatformFileHandle& handle)
  77. {
  78. if (isHandleValid(handle)) {
  79. close(handle);
  80. handle = invalidPlatformFileHandle;
  81. }
  82. }
  83. long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
  84. {
  85. int whence = SEEK_SET;
  86. switch (origin) {
  87. case SeekFromBeginning:
  88. whence = SEEK_SET;
  89. break;
  90. case SeekFromCurrent:
  91. whence = SEEK_CUR;
  92. break;
  93. case SeekFromEnd:
  94. whence = SEEK_END;
  95. break;
  96. default:
  97. ASSERT_NOT_REACHED();
  98. }
  99. return static_cast<long long>(lseek(handle, offset, whence));
  100. }
  101. bool truncateFile(PlatformFileHandle handle, long long offset)
  102. {
  103. // ftruncate returns 0 to indicate the success.
  104. return !ftruncate(handle, offset);
  105. }
  106. int writeToFile(PlatformFileHandle handle, const char* data, int length)
  107. {
  108. do {
  109. int bytesWritten = write(handle, data, static_cast<size_t>(length));
  110. if (bytesWritten >= 0)
  111. return bytesWritten;
  112. } while (errno == EINTR);
  113. return -1;
  114. }
  115. int readFromFile(PlatformFileHandle handle, char* data, int length)
  116. {
  117. do {
  118. int bytesRead = read(handle, data, static_cast<size_t>(length));
  119. if (bytesRead >= 0)
  120. return bytesRead;
  121. } while (errno == EINTR);
  122. return -1;
  123. }
  124. bool deleteEmptyDirectory(const String& path)
  125. {
  126. CString fsRep = fileSystemRepresentation(path);
  127. if (!fsRep.data() || fsRep.data()[0] == '\0')
  128. return false;
  129. // rmdir(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
  130. return !rmdir(fsRep.data());
  131. }
  132. bool getFileSize(const String& path, long long& result)
  133. {
  134. CString fsRep = fileSystemRepresentation(path);
  135. if (!fsRep.data() || fsRep.data()[0] == '\0')
  136. return false;
  137. struct stat fileInfo;
  138. if (stat(fsRep.data(), &fileInfo))
  139. return false;
  140. result = fileInfo.st_size;
  141. return true;
  142. }
  143. bool getFileModificationTime(const String& path, time_t& result)
  144. {
  145. CString fsRep = fileSystemRepresentation(path);
  146. if (!fsRep.data() || fsRep.data()[0] == '\0')
  147. return false;
  148. struct stat fileInfo;
  149. if (stat(fsRep.data(), &fileInfo))
  150. return false;
  151. result = fileInfo.st_mtime;
  152. return true;
  153. }
  154. String pathByAppendingComponent(const String& path, const String& component)
  155. {
  156. if (path.endsWith("/"))
  157. return path + component;
  158. return path + "/" + component;
  159. }
  160. bool makeAllDirectories(const String& path)
  161. {
  162. struct stat fileInfo;
  163. CString fullPath = fileSystemRepresentation(path);
  164. if (!stat(fullPath.data(), &fileInfo))
  165. return true;
  166. char* p = fullPath.mutableData() + 1;
  167. int length = fullPath.length();
  168. #if OS(ORBIS)
  169. const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
  170. #else
  171. const mode_t mode = S_IRWXU;
  172. #endif
  173. if (p[length - 1] == '/')
  174. p[length - 1] = '\0';
  175. for (; *p; ++p)
  176. if (*p == '/') {
  177. *p = '\0';
  178. if (stat(fullPath.data(), &fileInfo))
  179. if (mkdir(fullPath.data(), mode))
  180. return false;
  181. *p = '/';
  182. }
  183. if (stat(fullPath.data(), &fileInfo))
  184. if (mkdir(fullPath.data(), mode))
  185. return false;
  186. return true;
  187. }
  188. String pathGetFileName(const String& path)
  189. {
  190. return path.substring(path.reverseFind('/') + 1);
  191. }
  192. String directoryName(const String& path)
  193. {
  194. CString fsRep = fileSystemRepresentation(path);
  195. if (!fsRep.data() || fsRep.data()[0] == '\0')
  196. return String();
  197. return dirname(fsRep.mutableData());
  198. }
  199. Vector<String> listDirectory(const String& path, const String& filter)
  200. {
  201. Vector<String> entries;
  202. CString cpath = path.utf8();
  203. CString cfilter = filter.utf8();
  204. DIR* dir = opendir(cpath.data());
  205. if (dir) {
  206. struct dirent* dp;
  207. #if OS(PSP2) || OS(ORBIS)
  208. dirent de;
  209. while (!readdir_r(dir, &de, &dp) && dp) {
  210. #else
  211. while ((dp = readdir(dir))) {
  212. #endif
  213. const char* name = dp->d_name;
  214. if (!strcmp(name, ".") || !strcmp(name, ".."))
  215. continue;
  216. #if OS(PS3)
  217. if (fnmatch(cfilter.data(), name, 0))
  218. continue;
  219. #endif
  220. char filePath[1024];
  221. if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
  222. continue; // buffer overflow
  223. entries.append(filePath);
  224. }
  225. closedir(dir);
  226. }
  227. return entries;
  228. }
  229. String openTemporaryFile(const String& prefix, PlatformFileHandle& handle)
  230. {
  231. notImplemented();
  232. return String();
  233. }
  234. String homeDirectoryPath()
  235. {
  236. #if OS(PSP2)
  237. return String("host0:");
  238. #else
  239. return String(getenv("WEBKIT_HOME_DIR"));
  240. #endif
  241. }
  242. CString fileSystemRepresentation(const String& string)
  243. {
  244. return string.utf8();
  245. }
  246. bool unloadModule(PlatformModule)
  247. {
  248. return false;
  249. }
  250. bool getFileMetadata(const String& path, FileMetadata& metadata)
  251. {
  252. notImplemented();
  253. return false;
  254. }
  255. } // namespace WebCore