/src/3rdparty/webkit/Source/WebCore/platform/posix/FileSystemPOSIX.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 258 lines · 184 code · 43 blank · 31 comment · 52 complexity · 06b168b2a60d3a4c302a665a37a6fdb7 MD5 · raw file

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