⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287080 in webkit


Ignore:
Timestamp:
Dec 15, 2021, 9:50:28 AM (5 years ago)
Author:
tomoki.imai@sony.com
Message:

[PlayStation] Use FileSystem instead of FileSystemPlayStation except several unsupported APIs
https://bugs.webkit.org/show_bug.cgi?id=234337

Reviewed by Don Olmstead.

PlayStation should use FileSystem as its current SDK supports std::filesystem.
We have to maintain FileSystemPlayStation for now to supply some of FileSystem APIs
because the following functions are not supported yet.

  • std::filesystem::space
  • std::filesystem::rename
  • std::filesystem::canonical
  • std::filesystem::directory_iterator
  • std::filesystem::remove_all

The plan is to remove FileSystemPlayStation entirely after the SDK supports these functions.

This patch also fixes the incompatible issue of FileSystem::listDirectory of FileSystemPlayStation.
FileSystem::listDirectory is expected to return only the names, but it actually returns full paths.

Confirmed that there is no regression in FileSystem related testcases in TestWTF.

  • wtf/FileSystem.cpp: Add PLATFORM(PLAYSTATION) guards not to use unsupported std::filesystem APIs.
  • wtf/playstation/FileSystemPlayStation.cpp: Remove the functions duplicated with FileSystem.

Make FileSystem::listDirectory returns only names.
Add listDirectorySub which can return a full path because deleteNonEmptyDirectory depends on it.

Location:
trunk/Source/WTF
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r287072 r287080  
     12021-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
    1292021-12-15  Youenn Fablet  <youenn@apple.com>
    230
  • trunk/Source/WTF/wtf/FileSystem.cpp

    r286883 r287080  
    613613}
    614614
     615#if !PLATFORM(PLAYSTATION)
    615616bool moveFile(const String& oldPath, const String& newPath)
    616617{
     
    630631    return std::filesystem::remove_all(fsOldPath, ec);
    631632}
     633#endif
    632634
    633635std::optional<uint64_t> fileSize(const String& path)
     
    640642}
    641643
     644#if !PLATFORM(PLAYSTATION)
    642645std::optional<uint64_t> volumeFreeSpace(const String& path)
    643646{
     
    648651    return spaceInfo.available;
    649652}
     653#endif
    650654
    651655bool createSymbolicLink(const String& targetPath, const String& symbolicLinkPath)
     
    684688}
    685689
     690#if !PLATFORM(PLAYSTATION)
    686691bool deleteNonEmptyDirectory(const String& path)
    687692{
     
    690695    return !ec;
    691696}
     697#endif
    692698
    693699std::optional<WallTime> fileModificationTime(const String& path)
     
    757763}
    758764
     765#if !PLATFORM(PLAYSTATION)
    759766String realPath(const String& path)
    760767{
     
    763770    return ec ? path : fromStdFileSystemPath(canonicalPath);
    764771}
    765 
     772#endif
     773
     774#if !PLATFORM(PLAYSTATION)
    766775Vector<String> listDirectory(const String& path)
    767776{
     
    776785    return fileNames;
    777786}
     787#endif
    778788
    779789#if !ENABLE(FILESYSTEM_POSIX_FAST_PATH)
  • trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp

    r284533 r287080  
    3131#include <wtf/FileSystem.h>
    3232
    33 #if !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)
    34 
    3533#include <dirent.h>
    36 #include <libgen.h>
    3734#include <sys/statvfs.h>
    38 #include <sys/types.h>
    39 #include <unistd.h>
    40 #include <wtf/SafeStrerror.h>
    41 #include <wtf/text/StringBuilder.h>
    4235
    4336namespace WTF {
     
    6558}
    6659
    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 
    10860bool moveFile(const String& oldPath, const String& newPath)
    10961{
     
    11971}
    12072
    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 
    16573std::optional<uint64_t> volumeFreeSpace(const String& path)
    16674{
     
    17179}
    17280
    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)
     81Vector<String> listDirectorySub(const String& path, bool fullPath)
    33982{
    34083    Vector<String> entries;
     
    34790            if (!strcmp(name, ".") || !strcmp(name, ".."))
    34891                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
    35297
    353             auto string = stringFromFileSystemRepresentation(filePath);
     98                newEntry = stringFromFileSystemRepresentation(filePath);
     99            } else
     100                newEntry = stringFromFileSystemRepresentation(name);
    354101
    355102            // Some file system representations cannot be represented as a UTF-16 string,
    356             // so this string might 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));
    359106        }
    360107        closedir(dir);
     
    363110}
    364111
     112Vector<String> listDirectory(const String& path)
     113{
     114    return listDirectorySub(path, false);
     115}
     116
     117bool 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
     130String 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
    365140} // namespace FileSystemImpl
    366141} // namespace WTF
    367142
    368 #endif // !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)
Note: See TracChangeset for help on using the changeset viewer.