Changeset 287080 in webkit
- Timestamp:
- Dec 15, 2021, 9:50:28 AM (5 years ago)
- Location:
- trunk/Source/WTF
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
wtf/FileSystem.cpp (modified) (9 diffs)
-
wtf/playstation/FileSystemPlayStation.cpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r287072 r287080 1 2021-12-15 Tomoki Imai <tomoki.imai@sony.com> 2 3 [PlayStation] Use FileSystem instead of FileSystemPlayStation except several unsupported APIs 4 https://bugs.webkit.org/show_bug.cgi?id=234337 5 6 Reviewed by Don Olmstead. 7 8 PlayStation should use FileSystem as its current SDK supports std::filesystem. 9 We have to maintain FileSystemPlayStation for now to supply some of FileSystem APIs 10 because the following functions are not supported yet. 11 - std::filesystem::space 12 - std::filesystem::rename 13 - std::filesystem::canonical 14 - std::filesystem::directory_iterator 15 - std::filesystem::remove_all 16 17 The plan is to remove FileSystemPlayStation entirely after the SDK supports these functions. 18 19 This patch also fixes the incompatible issue of FileSystem::listDirectory of FileSystemPlayStation. 20 FileSystem::listDirectory is expected to return only the names, but it actually returns full paths. 21 22 Confirmed that there is no regression in FileSystem related testcases in TestWTF. 23 24 * wtf/FileSystem.cpp: Add PLATFORM(PLAYSTATION) guards not to use unsupported std::filesystem APIs. 25 * wtf/playstation/FileSystemPlayStation.cpp: Remove the functions duplicated with FileSystem. 26 Make FileSystem::listDirectory returns only names. 27 Add listDirectorySub which can return a full path because deleteNonEmptyDirectory depends on it. 28 1 29 2021-12-15 Youenn Fablet <youenn@apple.com> 2 30 -
trunk/Source/WTF/wtf/FileSystem.cpp
r286883 r287080 613 613 } 614 614 615 #if !PLATFORM(PLAYSTATION) 615 616 bool moveFile(const String& oldPath, const String& newPath) 616 617 { … … 630 631 return std::filesystem::remove_all(fsOldPath, ec); 631 632 } 633 #endif 632 634 633 635 std::optional<uint64_t> fileSize(const String& path) … … 640 642 } 641 643 644 #if !PLATFORM(PLAYSTATION) 642 645 std::optional<uint64_t> volumeFreeSpace(const String& path) 643 646 { … … 648 651 return spaceInfo.available; 649 652 } 653 #endif 650 654 651 655 bool createSymbolicLink(const String& targetPath, const String& symbolicLinkPath) … … 684 688 } 685 689 690 #if !PLATFORM(PLAYSTATION) 686 691 bool deleteNonEmptyDirectory(const String& path) 687 692 { … … 690 695 return !ec; 691 696 } 697 #endif 692 698 693 699 std::optional<WallTime> fileModificationTime(const String& path) … … 757 763 } 758 764 765 #if !PLATFORM(PLAYSTATION) 759 766 String realPath(const String& path) 760 767 { … … 763 770 return ec ? path : fromStdFileSystemPath(canonicalPath); 764 771 } 765 772 #endif 773 774 #if !PLATFORM(PLAYSTATION) 766 775 Vector<String> listDirectory(const String& path) 767 776 { … … 776 785 return fileNames; 777 786 } 787 #endif 778 788 779 789 #if !ENABLE(FILESYSTEM_POSIX_FAST_PATH) -
trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp
r284533 r287080 31 31 #include <wtf/FileSystem.h> 32 32 33 #if !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)34 35 33 #include <dirent.h> 36 #include <libgen.h>37 34 #include <sys/statvfs.h> 38 #include <sys/types.h>39 #include <unistd.h>40 #include <wtf/SafeStrerror.h>41 #include <wtf/text/StringBuilder.h>42 35 43 36 namespace WTF { … … 65 58 } 66 59 67 bool fileExists(const String& path)68 {69 if (path.isNull())70 return false;71 72 CString fsRep = fileSystemRepresentation(path);73 74 if (!fsRep.data() || fsRep.data()[0] == '\0')75 return false;76 77 return access(fsRep.data(), F_OK) != -1;78 }79 80 bool deleteFile(const String& path)81 {82 CString fsRep = fileSystemRepresentation(path);83 84 if (!fsRep.data() || fsRep.data()[0] == '\0') {85 LOG_ERROR("File failed to delete. Failed to get filesystem representation to create CString from cfString or filesystem representation is a null value");86 return false;87 }88 89 // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)90 bool unlinked = !unlink(fsRep.data());91 if (!unlinked && errno != ENOENT)92 LOG_ERROR("File failed to delete. Error message: %s", safeStrerror(errno).data());93 94 return unlinked;95 }96 97 bool deleteEmptyDirectory(const String& path)98 {99 CString fsRep = fileSystemRepresentation(path);100 101 if (!fsRep.data() || fsRep.data()[0] == '\0')102 return false;103 104 // rmdir(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)105 return !rmdir(fsRep.data());106 }107 108 60 bool moveFile(const String& oldPath, const String& newPath) 109 61 { … … 119 71 } 120 72 121 std::optional<uint64_t> fileSize(const String& path)122 {123 CString fsRep = fileSystemRepresentation(path);124 125 if (!fsRep.data() || fsRep.data()[0] == '\0')126 return std::nullopt;127 128 struct stat fileInfo;129 130 if (stat(fsRep.data(), &fileInfo))131 return std::nullopt;132 133 return fileInfo.st_size;134 }135 136 bool makeAllDirectories(const String& path)137 {138 CString fullPath = fileSystemRepresentation(path);139 if (!access(fullPath.data(), F_OK))140 return true;141 142 char* p = fullPath.mutableData() + 1;143 int length = fullPath.length();144 145 if (p[length - 1] == '/')146 p[length - 1] = '\0';147 for (; *p; ++p) {148 if (*p == '/') {149 *p = '\0';150 if (access(fullPath.data(), F_OK)) {151 if (mkdir(fullPath.data(), S_IRWXU))152 return false;153 }154 *p = '/';155 }156 }157 if (access(fullPath.data(), F_OK)) {158 if (mkdir(fullPath.data(), S_IRWXU))159 return false;160 }161 162 return true;163 }164 165 73 std::optional<uint64_t> volumeFreeSpace(const String& path) 166 74 { … … 171 79 } 172 80 173 bool createSymbolicLink(const String& targetPath, const String& symbolicLinkPath) 174 { 175 CString targetPathFSRep = fileSystemRepresentation(targetPath); 176 if (!targetPathFSRep.data() || targetPathFSRep.data()[0] == '\0') 177 return false; 178 179 CString symbolicLinkPathFSRep = fileSystemRepresentation(symbolicLinkPath); 180 if (!symbolicLinkPathFSRep.data() || symbolicLinkPathFSRep.data()[0] == '\0') 181 return false; 182 183 return !symlink(targetPathFSRep.data(), symbolicLinkPathFSRep.data()); 184 } 185 186 bool hardLink(const String& source, const String& destination) 187 { 188 if (source.isEmpty() || destination.isEmpty()) 189 return false; 190 191 auto fsSource = fileSystemRepresentation(source); 192 if (!fsSource.data()) 193 return false; 194 195 auto fsDestination = fileSystemRepresentation(destination); 196 if (!fsDestination.data()) 197 return false; 198 199 return !link(fsSource.data(), fsDestination.data()); 200 } 201 202 bool hardLinkOrCopyFile(const String& source, const String& destination) 203 { 204 if (hardLink(source, destination)) 205 return true; 206 207 // Hard link failed. Perform a copy instead. 208 if (source.isEmpty() || destination.isEmpty()) 209 return false; 210 211 auto fsSource = fileSystemRepresentation(source); 212 if (!fsSource.data()) 213 return false; 214 215 auto fsDestination = fileSystemRepresentation(destination); 216 if (!fsDestination.data()) 217 return false; 218 219 auto handle = open(fsDestination.data(), O_WRONLY | O_CREAT | O_EXCL, 0666); 220 if (handle == -1) 221 return false; 222 223 bool appendResult = appendFileContentsToFileHandle(source, handle); 224 close(handle); 225 226 // If the copy failed, delete the unusable file. 227 if (!appendResult) 228 unlink(fsDestination.data()); 229 230 return appendResult; 231 } 232 233 std::optional<uint64_t> hardLinkCount(const String& path) 234 { 235 auto linkPath = fileSystemRepresentation(path); 236 struct stat stat; 237 if (::stat(linkPath.data(), &stat) < 0) 238 return std::nullopt; 239 240 // Link count is 2 in the single client case (the blob file and a link). 241 return stat.st_nlink - 1; 242 } 243 244 bool deleteNonEmptyDirectory(const String& path) 245 { 246 auto entries = listDirectory(path); 247 for (auto& entry : entries) { 248 if (fileTypePotentiallyFollowingSymLinks(entry, ShouldFollowSymbolicLinks::No) == FileType::Directory) 249 deleteNonEmptyDirectory(entry); 250 else 251 deleteFile(entry); 252 } 253 return deleteEmptyDirectory(path); 254 } 255 256 std::optional<WallTime> fileModificationTime(const String& path) 257 { 258 CString fsRep = fileSystemRepresentation(path); 259 260 if (!fsRep.data() || fsRep.data()[0] == '\0') 261 return std::nullopt; 262 263 struct stat fileInfo; 264 265 if (stat(fsRep.data(), &fileInfo)) 266 return std::nullopt; 267 268 return WallTime::fromRawSeconds(fileInfo.st_mtime); 269 } 270 271 bool updateFileModificationTime(const String& path) 272 { 273 CString fsRep = fileSystemRepresentation(path); 274 275 if (!fsRep.data() || fsRep.data()[0] == '\0') 276 return false; 277 278 // Passing in null sets the modification time to now 279 return !utimes(fsRep.data(), nullptr); 280 } 281 282 bool isHiddenFile(const String& path) 283 { 284 auto filename = pathFileName(path); 285 286 return !filename.isEmpty() && filename[0] == '.'; 287 } 288 289 std::optional<FileType> fileType(const String& path) 290 { 291 return fileTypePotentiallyFollowingSymLinks(path, ShouldFollowSymbolicLinks::No); 292 } 293 294 std::optional<FileType> fileTypeFollowingSymlinks(const String& path) 295 { 296 return fileTypePotentiallyFollowingSymLinks(path, ShouldFollowSymbolicLinks::Yes); 297 } 298 299 String pathFileName(const String& path) 300 { 301 return path.substring(path.reverseFind('/') + 1); 302 } 303 304 String parentPath(const String& path) 305 { 306 CString fsRep = fileSystemRepresentation(path); 307 308 if (!fsRep.data() || fsRep.data()[0] == '\0') 309 return String(); 310 311 return String::fromUTF8(dirname(fsRep.mutableData())); 312 } 313 314 String realPath(const String& filePath) 315 { 316 CString fsRep = fileSystemRepresentation(filePath); 317 char resolvedName[PATH_MAX]; 318 const char* result = realpath(fsRep.data(), resolvedName); 319 return result ? String::fromUTF8(result) : filePath; 320 } 321 322 String pathByAppendingComponent(const String& path, const String& component) 323 { 324 if (path.endsWith('/')) 325 return path + component; 326 return path + "/" + component; 327 } 328 329 String pathByAppendingComponents(StringView path, const Vector<StringView>& components) 330 { 331 StringBuilder builder; 332 builder.append(path); 333 for (auto& component : components) 334 builder.append('/', component); 335 return builder.toString(); 336 } 337 338 Vector<String> listDirectory(const String& path) 81 Vector<String> listDirectorySub(const String& path, bool fullPath) 339 82 { 340 83 Vector<String> entries; … … 347 90 if (!strcmp(name, ".") || !strcmp(name, "..")) 348 91 continue; 349 char filePath[PATH_MAX]; 350 if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name)) 351 continue; // buffer overflow 92 String newEntry; 93 if (fullPath) { 94 char filePath[PATH_MAX]; 95 if (fullPath && static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name)) 96 continue; // buffer overflow 352 97 353 auto string = stringFromFileSystemRepresentation(filePath); 98 newEntry = stringFromFileSystemRepresentation(filePath); 99 } else 100 newEntry = stringFromFileSystemRepresentation(name); 354 101 355 102 // Some file system representations cannot be represented as a UTF-16 string, 356 // so this stringmight be null.357 if (! string.isNull())358 entries.append(WTFMove( string));103 // so this newEntry might be null. 104 if (!newEntry.isNull()) 105 entries.append(WTFMove(newEntry)); 359 106 } 360 107 closedir(dir); … … 363 110 } 364 111 112 Vector<String> listDirectory(const String& path) 113 { 114 return listDirectorySub(path, false); 115 } 116 117 bool deleteNonEmptyDirectory(const String& path) 118 { 119 auto entries = listDirectorySub(path, true); 120 for (auto& entry : entries) { 121 if (fileTypePotentiallyFollowingSymLinks(entry, ShouldFollowSymbolicLinks::No) == FileType::Directory) 122 deleteNonEmptyDirectory(entry); 123 else 124 deleteFile(entry); 125 } 126 return deleteEmptyDirectory(path); 127 } 128 129 130 String realPath(const String& filePath) 131 { 132 CString fsRep = fileSystemRepresentation(filePath); 133 char resolvedName[PATH_MAX]; 134 const char* result = realpath(fsRep.data(), resolvedName); 135 return result ? String::fromUTF8(result) : filePath; 136 } 137 138 139 365 140 } // namespace FileSystemImpl 366 141 } // namespace WTF 367 142 368 #endif // !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)
Note:
See TracChangeset
for help on using the changeset viewer.