• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 #include "config.h"
30 #include "FileSystem.h"
31 
32 #include "PlatformString.h"
33 #include <dirent.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <fnmatch.h>
37 #include <libgen.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #include <wtf/text/CString.h>
42 
43 namespace WebCore {
44 
fileExists(const String & path)45 bool fileExists(const String& path)
46 {
47     if (path.isNull())
48         return false;
49 
50     CString fsRep = fileSystemRepresentation(path);
51 
52     if (!fsRep.data() || fsRep.data()[0] == '\0')
53         return false;
54 
55     struct stat fileInfo;
56 
57     // 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
58     return !stat(fsRep.data(), &fileInfo);
59 }
60 
deleteFile(const String & path)61 bool deleteFile(const String& path)
62 {
63     CString fsRep = fileSystemRepresentation(path);
64 
65     if (!fsRep.data() || fsRep.data()[0] == '\0')
66         return false;
67 
68     // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
69     return !unlink(fsRep.data());
70 }
71 
openFile(const String & path,FileOpenMode mode)72 PlatformFileHandle openFile(const String& path, FileOpenMode mode)
73 {
74     CString fsRep = fileSystemRepresentation(path);
75 
76     if (fsRep.isNull())
77         return invalidPlatformFileHandle;
78 
79     int platformFlag = 0;
80     if (mode == OpenForRead)
81         platformFlag |= O_RDONLY;
82     else if (mode == OpenForWrite)
83         platformFlag |= (O_WRONLY | O_CREAT | O_TRUNC);
84     return open(fsRep.data(), platformFlag, 0666);
85 }
86 
closeFile(PlatformFileHandle & handle)87 void closeFile(PlatformFileHandle& handle)
88 {
89     if (isHandleValid(handle)) {
90         close(handle);
91         handle = invalidPlatformFileHandle;
92     }
93 }
94 
seekFile(PlatformFileHandle handle,long long offset,FileSeekOrigin origin)95 long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
96 {
97     int whence = SEEK_SET;
98     switch (origin) {
99     case SeekFromBeginning:
100         whence = SEEK_SET;
101         break;
102     case SeekFromCurrent:
103         whence = SEEK_CUR;
104         break;
105     case SeekFromEnd:
106         whence = SEEK_END;
107         break;
108     default:
109         ASSERT_NOT_REACHED();
110     }
111     return static_cast<long long>(lseek(handle, offset, whence));
112 }
113 
truncateFile(PlatformFileHandle handle,long long offset)114 bool truncateFile(PlatformFileHandle handle, long long offset)
115 {
116     // ftruncate returns 0 to indicate the success.
117     return !ftruncate(handle, offset);
118 }
119 
writeToFile(PlatformFileHandle handle,const char * data,int length)120 int writeToFile(PlatformFileHandle handle, const char* data, int length)
121 {
122     do {
123         int bytesWritten = write(handle, data, static_cast<size_t>(length));
124         if (bytesWritten >= 0)
125             return bytesWritten;
126     } while (errno == EINTR);
127     return -1;
128 }
129 
readFromFile(PlatformFileHandle handle,char * data,int length)130 int readFromFile(PlatformFileHandle handle, char* data, int length)
131 {
132     do {
133         int bytesRead = read(handle, data, static_cast<size_t>(length));
134         if (bytesRead >= 0)
135             return bytesRead;
136     } while (errno == EINTR);
137     return -1;
138 }
139 
deleteEmptyDirectory(const String & path)140 bool deleteEmptyDirectory(const String& path)
141 {
142     CString fsRep = fileSystemRepresentation(path);
143 
144     if (!fsRep.data() || fsRep.data()[0] == '\0')
145         return false;
146 
147     // rmdir(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
148     return !rmdir(fsRep.data());
149 }
150 
getFileSize(const String & path,long long & result)151 bool getFileSize(const String& path, long long& result)
152 {
153     CString fsRep = fileSystemRepresentation(path);
154 
155     if (!fsRep.data() || fsRep.data()[0] == '\0')
156         return false;
157 
158     struct stat fileInfo;
159 
160     if (stat(fsRep.data(), &fileInfo))
161         return false;
162 
163     result = fileInfo.st_size;
164     return true;
165 }
166 
getFileModificationTime(const String & path,time_t & result)167 bool getFileModificationTime(const String& path, time_t& result)
168 {
169     CString fsRep = fileSystemRepresentation(path);
170 
171     if (!fsRep.data() || fsRep.data()[0] == '\0')
172         return false;
173 
174     struct stat fileInfo;
175 
176     if (stat(fsRep.data(), &fileInfo))
177         return false;
178 
179     result = fileInfo.st_mtime;
180     return true;
181 }
182 
pathByAppendingComponent(const String & path,const String & component)183 String pathByAppendingComponent(const String& path, const String& component)
184 {
185     if (path.endsWith("/"))
186         return path + component;
187     else
188         return path + "/" + component;
189 }
190 
makeAllDirectories(const String & path)191 bool makeAllDirectories(const String& path)
192 {
193     CString fullPath = fileSystemRepresentation(path);
194     if (!access(fullPath.data(), F_OK))
195         return true;
196 
197     char* p = fullPath.mutableData() + 1;
198     int length = fullPath.length();
199 
200     if(p[length - 1] == '/')
201         p[length - 1] = '\0';
202     for (; *p; ++p)
203         if (*p == '/') {
204             *p = '\0';
205             if (access(fullPath.data(), F_OK))
206                 if (mkdir(fullPath.data(), S_IRWXU))
207                     return false;
208             *p = '/';
209         }
210     if (access(fullPath.data(), F_OK))
211         if (mkdir(fullPath.data(), S_IRWXU))
212             return false;
213 
214     return true;
215 }
216 
217 #if !PLATFORM(ANDROID)
pathGetFileName(const String & path)218 String pathGetFileName(const String& path)
219 {
220     return path.substring(path.reverseFind('/') + 1);
221 }
222 #endif
223 
directoryName(const String & path)224 String directoryName(const String& path)
225 {
226     CString fsRep = fileSystemRepresentation(path);
227 
228     if (!fsRep.data() || fsRep.data()[0] == '\0')
229         return String();
230 
231     return dirname(fsRep.mutableData());
232 }
233 
234 #if !PLATFORM(EFL)
listDirectory(const String & path,const String & filter)235 Vector<String> listDirectory(const String& path, const String& filter)
236 {
237     Vector<String> entries;
238     CString cpath = path.utf8();
239     CString cfilter = filter.utf8();
240     DIR* dir = opendir(cpath.data());
241     if (dir) {
242         struct dirent* dp;
243         while ((dp = readdir(dir))) {
244             const char* name = dp->d_name;
245             if (!strcmp(name, ".") || !strcmp(name, ".."))
246                 continue;
247             if (fnmatch(cfilter.data(), name, 0))
248                 continue;
249             char filePath[1024];
250             if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
251                 continue; // buffer overflow
252             entries.append(filePath);
253         }
254         closedir(dir);
255     }
256     return entries;
257 }
258 #endif
259 
260 } // namespace WebCore
261