2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "FileSystem.h"
32 #include "FileMetadata.h"
33 #include "PlatformString.h"
41 #include <sys/types.h>
44 #include <wtf/text/CString.h>
46 #if ENABLE(TIZEN_SOUP_COOKIE_CACHE_FOR_WEBKIT2)
47 #include <sys/statvfs.h>
52 bool fileExists(const String& path)
57 CString fsRep = fileSystemRepresentation(path);
59 if (!fsRep.data() || fsRep.data()[0] == '\0')
64 // 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
65 return !stat(fsRep.data(), &fileInfo);
68 bool deleteFile(const String& path)
70 CString fsRep = fileSystemRepresentation(path);
72 if (!fsRep.data() || fsRep.data()[0] == '\0')
75 // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
76 return !unlink(fsRep.data());
79 PlatformFileHandle openFile(const String& path, FileOpenMode mode)
81 CString fsRep = fileSystemRepresentation(path);
84 return invalidPlatformFileHandle;
87 if (mode == OpenForRead)
88 platformFlag |= O_RDONLY;
89 else if (mode == OpenForWrite)
90 platformFlag |= (O_WRONLY | O_CREAT | O_TRUNC);
91 return open(fsRep.data(), platformFlag, 0666);
94 void closeFile(PlatformFileHandle& handle)
96 if (isHandleValid(handle)) {
98 handle = invalidPlatformFileHandle;
102 long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
104 int whence = SEEK_SET;
106 case SeekFromBeginning:
109 case SeekFromCurrent:
116 ASSERT_NOT_REACHED();
118 return static_cast<long long>(lseek(handle, offset, whence));
121 bool truncateFile(PlatformFileHandle handle, long long offset)
123 // ftruncate returns 0 to indicate the success.
124 return !ftruncate(handle, offset);
127 int writeToFile(PlatformFileHandle handle, const char* data, int length)
130 int bytesWritten = write(handle, data, static_cast<size_t>(length));
131 if (bytesWritten >= 0)
133 } while (errno == EINTR);
137 int readFromFile(PlatformFileHandle handle, char* data, int length)
140 int bytesRead = read(handle, data, static_cast<size_t>(length));
143 } while (errno == EINTR);
147 bool deleteEmptyDirectory(const String& path)
149 CString fsRep = fileSystemRepresentation(path);
151 if (!fsRep.data() || fsRep.data()[0] == '\0')
154 // rmdir(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
155 return !rmdir(fsRep.data());
158 bool getFileSize(const String& path, long long& result)
160 CString fsRep = fileSystemRepresentation(path);
162 if (!fsRep.data() || fsRep.data()[0] == '\0')
165 struct stat fileInfo;
167 if (stat(fsRep.data(), &fileInfo))
170 result = fileInfo.st_size;
174 bool getFileModificationTime(const String& path, time_t& result)
176 CString fsRep = fileSystemRepresentation(path);
178 if (!fsRep.data() || fsRep.data()[0] == '\0')
181 struct stat fileInfo;
183 if (stat(fsRep.data(), &fileInfo))
186 result = fileInfo.st_mtime;
190 #if !ENABLE(TIZEN_FILE_SYSTEM)
191 bool getFileMetadata(const String& path, FileMetadata& metadata)
193 CString fsRep = fileSystemRepresentation(path);
195 if (!fsRep.data() || fsRep.data()[0] == '\0')
198 struct stat fileInfo;
199 if (stat(fsRep.data(), &fileInfo))
202 metadata.modificationTime = fileInfo.st_mtime;
203 metadata.length = fileInfo.st_size;
204 metadata.type = S_ISDIR(fileInfo.st_mode) ? FileMetadata::TypeDirectory : FileMetadata::TypeFile;
209 String pathByAppendingComponent(const String& path, const String& component)
211 if (path.endsWith('/'))
212 return path + component;
213 return path + "/" + component;
216 bool makeAllDirectories(const String& path)
218 CString fullPath = fileSystemRepresentation(path);
219 if (!access(fullPath.data(), F_OK))
222 char* p = fullPath.mutableData() + 1;
223 int length = fullPath.length();
225 if(p[length - 1] == '/')
226 p[length - 1] = '\0';
230 if (access(fullPath.data(), F_OK))
231 if (mkdir(fullPath.data(), S_IRWXU))
235 if (access(fullPath.data(), F_OK))
236 if (mkdir(fullPath.data(), S_IRWXU))
242 String pathGetFileName(const String& path)
244 return path.substring(path.reverseFind('/') + 1);
247 String directoryName(const String& path)
249 CString fsRep = fileSystemRepresentation(path);
251 if (!fsRep.data() || fsRep.data()[0] == '\0')
254 return dirname(fsRep.mutableData());
258 Vector<String> listDirectory(const String& path, const String& filter)
260 Vector<String> entries;
261 CString cpath = path.utf8();
262 CString cfilter = filter.utf8();
263 DIR* dir = opendir(cpath.data());
266 while ((dp = readdir(dir))) {
267 const char* name = dp->d_name;
268 if (!strcmp(name, ".") || !strcmp(name, ".."))
270 if (fnmatch(cfilter.data(), name, 0))
273 if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
274 continue; // buffer overflow
275 entries.append(filePath);
283 #if ENABLE(TIZEN_SOUP_COOKIE_CACHE_FOR_WEBKIT2)
284 uint64_t getVolumeFreeSizeForPath(const char* path)
287 if (!statvfs(path, &buf)) {
288 uint64_t freeSize = buf.f_bsize * buf.f_bfree;
295 #if ENABLE(TIZEN_FILE_SYSTEM)
296 bool copyFile(const String& sourcePath, const String& destinationPath)
298 if (!fileExists(sourcePath))
301 if (destinationPath.isEmpty())
304 PlatformFileHandle srcFile = openFile(sourcePath, OpenForRead);
305 if (srcFile == invalidPlatformFileHandle)
308 PlatformFileHandle dstFile = openFile(destinationPath, OpenForWrite);
309 if (dstFile == invalidPlatformFileHandle) {
317 while ((readSize = read(srcFile, buffer, 1024)) > 0) {
318 if ((writeSize = write(dstFile, buffer, readSize)) == -1) {
331 bool removeDirectory(const String& path)
333 if(!fileExists(path))
336 DIR* directory = opendir(fileSystemRepresentation(path).data());
340 struct dirent* directoryEntry;
343 while (directoryEntry = readdir(directory)) {
344 if (!strcmp(directoryEntry->d_name, ".") || !strcmp(directoryEntry->d_name, ".."))
347 String absolutePath = pathByAppendingComponent(path, String(directoryEntry->d_name));
349 if (lstat(absolutePath.utf8().data(), &buf) == -1) {
355 if (S_ISDIR(buf.st_mode))
356 result = removeDirectory(absolutePath);
358 result = deleteFile(absolutePath);
367 return deleteEmptyDirectory(path);
369 #endif // ENABLE(TIZEN_FILE_SYSTEM)
372 String openTemporaryFile(const String& prefix, PlatformFileHandle& handle)
374 char buffer[PATH_MAX];
375 const char* tmpDir = getenv("TMPDIR");
380 if (snprintf(buffer, PATH_MAX, "%s/%sXXXXXX", tmpDir, prefix.utf8().data()) >= PATH_MAX)
383 handle = mkstemp(buffer);
387 return String::fromUTF8(buffer);
390 handle = invalidPlatformFileHandle;
395 } // namespace WebCore