<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[278027] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/278027">278027</a></dd>
<dt>Author</dt> <dd>don.olmstead@sony.com</dd>
<dt>Date</dt> <dd>2021-05-25 10:34:01 -0700 (Tue, 25 May 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[PlayStation] Implement FileSystem without std::filesystem
https://bugs.webkit.org/show_bug.cgi?id=226197

Reviewed by Chris Dumez.

.:

Expose the result of the check for <filesystem> support as HAVE_STD_FILESYSTEM.

* Source/cmake/OptionsCommon.cmake:

Source/WTF:

The PlayStation 4 doesn't have support in its SDK for std::filesystem so backport the
functions jettisoned from FileSystemPOSIX and add them to a FileSystemPlayStation.cpp.
The ordering matches the contents of FileSystem.cpp.

Most of the functions ported to std::filesystem were just moved over as is from the commit
prior to <a href="http://trac.webkit.org/projects/webkit/changeset/276879">r276879</a>. Minor changes to the function signatures made when required.

The fileTypePotentiallyFollowingSymLinks function was created from the previous behavior
of fileMetadataUsingFunction and toFileMetataType.

The hardLinkCount was created from looking at the behavior hardLinkCount replaced in
<a href="http://trac.webkit.org/projects/webkit/changeset/277446">r277446</a>.

* wtf/FileSystem.cpp:
* wtf/PlatformHave.h:
* wtf/PlatformPlayStation.cmake:
* wtf/StdFilesystem.h:
* wtf/playstation/FileSystemPlayStation.cpp: Added.
(WTF::FileSystemImpl::fileTypePotentiallyFollowingSymLinks):
(WTF::FileSystemImpl::fileExists):
(WTF::FileSystemImpl::deleteFile):
(WTF::FileSystemImpl::deleteEmptyDirectory):
(WTF::FileSystemImpl::moveFile):
(WTF::FileSystemImpl::fileSize):
(WTF::FileSystemImpl::makeAllDirectories):
(WTF::FileSystemImpl::volumeFreeSpace):
(WTF::FileSystemImpl::createSymbolicLink):
(WTF::FileSystemImpl::hardLink):
(WTF::FileSystemImpl::hardLinkOrCopyFile):
(WTF::FileSystemImpl::hardLinkCount):
(WTF::FileSystemImpl::deleteNonEmptyDirectory):
(WTF::FileSystemImpl::fileModificationTime):
(WTF::FileSystemImpl::updateFileModificationTime):
(WTF::FileSystemImpl::isHiddenFile):
(WTF::FileSystemImpl::fileType):
(WTF::FileSystemImpl::fileTypeFollowingSymlinks):
(WTF::FileSystemImpl::pathFileName):
(WTF::FileSystemImpl::parentPath):
(WTF::FileSystemImpl::realPath):
(WTF::FileSystemImpl::pathByAppendingComponent):
(WTF::FileSystemImpl::pathByAppendingComponents):
(WTF::FileSystemImpl::listDirectory):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkChangeLog">trunk/ChangeLog</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfFileSystemcpp">trunk/Source/WTF/wtf/FileSystem.cpp</a></li>
<li><a href="#trunkSourceWTFwtfPlatformHaveh">trunk/Source/WTF/wtf/PlatformHave.h</a></li>
<li><a href="#trunkSourceWTFwtfPlatformPlayStationcmake">trunk/Source/WTF/wtf/PlatformPlayStation.cmake</a></li>
<li><a href="#trunkSourceWTFwtfStdFilesystemh">trunk/Source/WTF/wtf/StdFilesystem.h</a></li>
<li><a href="#trunkSourcecmakeOptionsCommoncmake">trunk/Source/cmake/OptionsCommon.cmake</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWTFwtfplaystationFileSystemPlayStationcpp">trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/ChangeLog (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/ChangeLog  2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/ChangeLog     2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2021-05-25  Don Olmstead  <don.olmstead@sony.com>
+
+        [PlayStation] Implement FileSystem without std::filesystem
+        https://bugs.webkit.org/show_bug.cgi?id=226197
+
+        Reviewed by Chris Dumez.
+
+        Expose the result of the check for <filesystem> support as HAVE_STD_FILESYSTEM.
+
+        * Source/cmake/OptionsCommon.cmake:
+
</ins><span class="cx"> 2021-05-18  Yoshiaki Jitsukawa  <yoshiaki.jitsukawa@sony.com>
</span><span class="cx"> 
</span><span class="cx">         [PlayStation] Fix PlayStation port
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/WTF/ChangeLog  2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2021-05-25  Don Olmstead  <don.olmstead@sony.com>
+
+        [PlayStation] Implement FileSystem without std::filesystem
+        https://bugs.webkit.org/show_bug.cgi?id=226197
+
+        Reviewed by Chris Dumez.
+
+        The PlayStation 4 doesn't have support in its SDK for std::filesystem so backport the
+        functions jettisoned from FileSystemPOSIX and add them to a FileSystemPlayStation.cpp.
+        The ordering matches the contents of FileSystem.cpp.
+
+        Most of the functions ported to std::filesystem were just moved over as is from the commit
+        prior to r276879. Minor changes to the function signatures made when required.
+
+        The fileTypePotentiallyFollowingSymLinks function was created from the previous behavior
+        of fileMetadataUsingFunction and toFileMetataType.
+
+        The hardLinkCount was created from looking at the behavior hardLinkCount replaced in
+        r277446.
+
+        * wtf/FileSystem.cpp:
+        * wtf/PlatformHave.h:
+        * wtf/PlatformPlayStation.cmake:
+        * wtf/StdFilesystem.h:
+        * wtf/playstation/FileSystemPlayStation.cpp: Added.
+        (WTF::FileSystemImpl::fileTypePotentiallyFollowingSymLinks):
+        (WTF::FileSystemImpl::fileExists):
+        (WTF::FileSystemImpl::deleteFile):
+        (WTF::FileSystemImpl::deleteEmptyDirectory):
+        (WTF::FileSystemImpl::moveFile):
+        (WTF::FileSystemImpl::fileSize):
+        (WTF::FileSystemImpl::makeAllDirectories):
+        (WTF::FileSystemImpl::volumeFreeSpace):
+        (WTF::FileSystemImpl::createSymbolicLink):
+        (WTF::FileSystemImpl::hardLink):
+        (WTF::FileSystemImpl::hardLinkOrCopyFile):
+        (WTF::FileSystemImpl::hardLinkCount):
+        (WTF::FileSystemImpl::deleteNonEmptyDirectory):
+        (WTF::FileSystemImpl::fileModificationTime):
+        (WTF::FileSystemImpl::updateFileModificationTime):
+        (WTF::FileSystemImpl::isHiddenFile):
+        (WTF::FileSystemImpl::fileType):
+        (WTF::FileSystemImpl::fileTypeFollowingSymlinks):
+        (WTF::FileSystemImpl::pathFileName):
+        (WTF::FileSystemImpl::parentPath):
+        (WTF::FileSystemImpl::realPath):
+        (WTF::FileSystemImpl::pathByAppendingComponent):
+        (WTF::FileSystemImpl::pathByAppendingComponents):
+        (WTF::FileSystemImpl::listDirectory):
+
</ins><span class="cx"> 2021-05-24  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Stop using UncheckedLock in WTF::RecursiveLock
</span></span></pre></div>
<a id="trunkSourceWTFwtfFileSystemcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/FileSystem.cpp (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/FileSystem.cpp      2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/WTF/wtf/FileSystem.cpp 2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -30,7 +30,6 @@
</span><span class="cx"> #include <wtf/CryptographicallyRandomNumber.h>
</span><span class="cx"> #include <wtf/HexNumber.h>
</span><span class="cx"> #include <wtf/Scope.h>
</span><del>-#include <wtf/StdFilesystem.h>
</del><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx"> #include <wtf/text/StringBuilder.h>
</span><span class="cx"> 
</span><span class="lines">@@ -45,10 +44,16 @@
</span><span class="cx"> #include <gio/gio.h>
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+#include <wtf/StdFilesystem.h>
+#endif
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> namespace FileSystemImpl {
</span><span class="cx"> 
</span><ins>+#if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> static std::filesystem::path toStdFileSystemPath(StringView path)
</span><span class="cx"> {
</span><span class="cx">     return std::filesystem::u8path(path.utf8().data());
</span><span class="lines">@@ -59,6 +64,8 @@
</span><span class="cx">     return String::fromUTF8(path.u8string().c_str());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif // HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> // The following lower-ASCII characters need escaping to be used in a filename
</span><span class="cx"> // across all systems, including Windows:
</span><span class="cx"> //     - Unprintable ASCII (00-1F)
</span><span class="lines">@@ -115,6 +122,8 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> template<typename ClockType, typename = void> struct has_to_time_t : std::false_type { };
</span><span class="cx"> template<typename ClockType> struct has_to_time_t<ClockType, std::void_t<
</span><span class="cx">     std::enable_if_t<std::is_same_v<std::time_t, decltype(ClockType::to_time_t(std::filesystem::file_time_type()))>>
</span><span class="lines">@@ -138,6 +147,8 @@
</span><span class="cx">     return WallTime::fromRawSeconds(toTimeT(fileTime));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif // HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> String encodeForFileName(const String& inputString)
</span><span class="cx"> {
</span><span class="cx">     unsigned length = inputString.length();
</span><span class="lines">@@ -509,6 +520,8 @@
</span><span class="cx">     return salt;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> bool fileExists(const String& path)
</span><span class="cx"> {
</span><span class="cx">     std::error_code ec;
</span><span class="lines">@@ -741,5 +754,7 @@
</span><span class="cx">     return fileNames;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif // HAVE(STD_FILESYSTEM) || HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
</ins><span class="cx"> } // namespace FileSystemImpl
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformHaveh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PlatformHave.h (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PlatformHave.h      2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/WTF/wtf/PlatformHave.h 2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -93,6 +93,22 @@
</span><span class="cx"> #define HAVE_ACCESSIBILITY 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if !defined(HAVE_STD_FILESYSTEM)
+#if __has_include(<filesystem>)
+#define HAVE_STD_FILESYSTEM 1
+#else
+#define HAVE_STD_FILESYSTEM 0
+#endif
+#endif
+
+#if !defined(HAVE_STD_EXPERIMENTAL_FILESYSTEM)
+#if __has_include(<experimental/filesystem>)
+#define STD_EXPERIMENTAL_FILESYSTEM 1
+#else
+#define STD_EXPERIMENTAL_FILESYSTEM 0
+#endif
+#endif
+
</ins><span class="cx"> /* FIXME: Remove after CMake build enabled on Darwin */
</span><span class="cx"> #if OS(DARWIN)
</span><span class="cx"> #define HAVE_ERRNO_H 1
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformPlayStationcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PlatformPlayStation.cmake (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PlatformPlayStation.cmake   2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/WTF/wtf/PlatformPlayStation.cmake      2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -4,6 +4,7 @@
</span><span class="cx">     generic/RunLoopGeneric.cpp
</span><span class="cx">     generic/WorkQueueGeneric.cpp
</span><span class="cx"> 
</span><ins>+    playstation/FileSystemPlayStation.cpp
</ins><span class="cx">     playstation/LanguagePlayStation.cpp
</span><span class="cx">     playstation/UniStdExtrasPlayStation.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfStdFilesystemh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/StdFilesystem.h (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/StdFilesystem.h     2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/WTF/wtf/StdFilesystem.h        2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -23,7 +23,9 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#if __has_include(<filesystem>)
</del><ins>+#pragma once
+
+#if HAVE(STD_FILESYSTEM)
</ins><span class="cx"> #include <filesystem>
</span><span class="cx"> #elif HAVE(STD_EXPERIMENTAL_FILESYSTEM)
</span><span class="cx"> #include <experimental/filesystem>
</span></span></pre></div>
<a id="trunkSourceWTFwtfplaystationFileSystemPlayStationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp (0 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp                               (rev 0)
+++ trunk/Source/WTF/wtf/playstation/FileSystemPlayStation.cpp  2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -0,0 +1,367 @@
</span><ins>+/*
+ * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/FileSystem.h>
+
+#if !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)
+
+#include <dirent.h>
+#include <libgen.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WTF {
+
+namespace FileSystemImpl {
+
+enum class ShouldFollowSymbolicLinks { No, Yes };
+static Optional<FileType> fileTypePotentiallyFollowingSymLinks(const String& path, ShouldFollowSymbolicLinks shouldFollowSymbolicLinks)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return WTF::nullopt;
+
+    auto statFunc = shouldFollowSymbolicLinks == ShouldFollowSymbolicLinks::Yes ? stat : lstat;
+    struct stat fileInfo;
+    if (statFunc(fsRep.data(), &fileInfo))
+        return WTF::nullopt;
+
+    if (S_ISDIR(fileInfo.st_mode))
+        return FileType::Directory;
+    if (S_ISLNK(fileInfo.st_mode))
+        return FileType::SymbolicLink;
+    return FileType::Regular;
+}
+
+bool fileExists(const String& path)
+{
+    if (path.isNull())
+        return false;
+
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return false;
+
+    return access(fsRep.data(), F_OK) != -1;
+}
+
+bool deleteFile(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0') {
+        LOG_ERROR("File failed to delete. Failed to get filesystem representation to create CString from cfString or filesystem representation is a null value");
+        return false;
+    }
+
+    // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
+    bool unlinked = !unlink(fsRep.data());
+    if (!unlinked && errno != ENOENT)
+        LOG_ERROR("File failed to delete. Error message: %s", strerror(errno));
+
+    return unlinked;
+}
+
+bool deleteEmptyDirectory(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return false;
+
+    // rmdir(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
+    return !rmdir(fsRep.data());
+}
+
+bool moveFile(const String& oldPath, const String& newPath)
+{
+    auto oldFilename = fileSystemRepresentation(oldPath);
+    if (oldFilename.isNull())
+        return false;
+
+    auto newFilename = fileSystemRepresentation(newPath);
+    if (newFilename.isNull())
+        return false;
+
+    return rename(oldFilename.data(), newFilename.data()) != -1;
+}
+
+Optional<uint64_t> fileSize(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return WTF::nullopt;
+
+    struct stat fileInfo;
+
+    if (stat(fsRep.data(), &fileInfo))
+        return WTF::nullopt;
+
+    return fileInfo.st_size;
+}
+
+bool makeAllDirectories(const String& path)
+{
+    CString fullPath = fileSystemRepresentation(path);
+    if (!access(fullPath.data(), F_OK))
+        return true;
+
+    char* p = fullPath.mutableData() + 1;
+    int length = fullPath.length();
+
+    if (p[length - 1] == '/')
+        p[length - 1] = '\0';
+    for (; *p; ++p) {
+        if (*p == '/') {
+            *p = '\0';
+            if (access(fullPath.data(), F_OK)) {
+                if (mkdir(fullPath.data(), S_IRWXU))
+                    return false;
+            }
+            *p = '/';
+        }
+    }
+    if (access(fullPath.data(), F_OK)) {
+        if (mkdir(fullPath.data(), S_IRWXU))
+            return false;
+    }
+
+    return true;
+}
+
+Optional<uint64_t> volumeFreeSpace(const String& path)
+{
+    struct statvfs fileSystemStat;
+    if (!statvfs(fileSystemRepresentation(path).data(), &fileSystemStat))
+        return fileSystemStat.f_bavail * fileSystemStat.f_frsize;
+    return WTF::nullopt;
+}
+
+bool createSymbolicLink(const String& targetPath, const String& symbolicLinkPath)
+{
+    CString targetPathFSRep = fileSystemRepresentation(targetPath);
+    if (!targetPathFSRep.data() || targetPathFSRep.data()[0] == '\0')
+        return false;
+
+    CString symbolicLinkPathFSRep = fileSystemRepresentation(symbolicLinkPath);
+    if (!symbolicLinkPathFSRep.data() || symbolicLinkPathFSRep.data()[0] == '\0')
+        return false;
+
+    return !symlink(targetPathFSRep.data(), symbolicLinkPathFSRep.data());
+}
+
+bool hardLink(const String& source, const String& destination)
+{
+    if (source.isEmpty() || destination.isEmpty())
+        return false;
+
+    auto fsSource = fileSystemRepresentation(source);
+    if (!fsSource.data())
+        return false;
+
+    auto fsDestination = fileSystemRepresentation(destination);
+    if (!fsDestination.data())
+        return false;
+
+    return !link(fsSource.data(), fsDestination.data());
+}
+
+bool hardLinkOrCopyFile(const String& source, const String& destination)
+{
+    if (hardLink(source, destination))
+        return true;
+
+    // Hard link failed. Perform a copy instead.
+    if (source.isEmpty() || destination.isEmpty())
+        return false;
+
+    auto fsSource = fileSystemRepresentation(source);
+    if (!fsSource.data())
+        return false;
+
+    auto fsDestination = fileSystemRepresentation(destination);
+    if (!fsDestination.data())
+        return false;
+
+    auto handle = open(fsDestination.data(), O_WRONLY | O_CREAT | O_EXCL, 0666);
+    if (handle == -1)
+        return false;
+
+    bool appendResult = appendFileContentsToFileHandle(source, handle);
+    close(handle);
+
+    // If the copy failed, delete the unusable file.
+    if (!appendResult)
+        unlink(fsDestination.data());
+
+    return appendResult;
+}
+
+Optional<uint64_t> hardLinkCount(const String& path)
+{
+    auto linkPath = fileSystemRepresentation(path);
+    struct stat stat;
+    if (::stat(linkPath.data(), &stat) < 0)
+        return WTF::nullopt;
+
+    // Link count is 2 in the single client case (the blob file and a link).
+    return stat.st_nlink - 1;
+}
+
+bool deleteNonEmptyDirectory(const String& path)
+{
+    auto entries = listDirectory(path);
+    for (auto& entry : entries) {
+        if (fileTypePotentiallyFollowingSymLinks(entry, ShouldFollowSymbolicLinks::No) == FileType::Directory)
+            deleteNonEmptyDirectory(entry);
+        else
+            deleteFile(entry);
+    }
+    return deleteEmptyDirectory(path);
+}
+
+Optional<WallTime> fileModificationTime(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return WTF::nullopt;
+
+    struct stat fileInfo;
+
+    if (stat(fsRep.data(), &fileInfo))
+        return WTF::nullopt;
+
+    return WallTime::fromRawSeconds(fileInfo.st_mtime);
+}
+
+bool updateFileModificationTime(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return false;
+
+    // Passing in null sets the modification time to now
+    return !utimes(fsRep.data(), nullptr);
+}
+
+bool isHiddenFile(const String& path)
+{
+    auto filename = pathFileName(path);
+
+    return !filename.isEmpty() && filename[0] == '.';
+}
+
+Optional<FileType> fileType(const String& path)
+{
+    return fileTypePotentiallyFollowingSymLinks(path, ShouldFollowSymbolicLinks::No);
+}
+
+Optional<FileType> fileTypeFollowingSymlinks(const String& path)
+{
+    return fileTypePotentiallyFollowingSymLinks(path, ShouldFollowSymbolicLinks::Yes);
+}
+
+String pathFileName(const String& path)
+{
+    return path.substring(path.reverseFind('/') + 1);
+}
+
+String parentPath(const String& path)
+{
+    CString fsRep = fileSystemRepresentation(path);
+
+    if (!fsRep.data() || fsRep.data()[0] == '\0')
+        return String();
+
+    return String::fromUTF8(dirname(fsRep.mutableData()));
+}
+
+String realPath(const String& filePath)
+{
+    CString fsRep = fileSystemRepresentation(filePath);
+    char resolvedName[PATH_MAX];
+    const char* result = realpath(fsRep.data(), resolvedName);
+    return result ? String::fromUTF8(result) : filePath;
+}
+
+String pathByAppendingComponent(const String& path, const String& component)
+{
+    if (path.endsWith('/'))
+        return path + component;
+    return path + "/" + component;
+}
+
+String pathByAppendingComponents(StringView path, const Vector<StringView>& components)
+{
+    StringBuilder builder;
+    builder.append(path);
+    for (auto& component : components)
+        builder.append('/', component);
+    return builder.toString();
+}
+
+Vector<String> listDirectory(const String& path)
+{
+    Vector<String> entries;
+    CString cpath = fileSystemRepresentation(path);
+    DIR* dir = opendir(cpath.data());
+    if (dir) {
+        struct dirent* dp;
+        while ((dp = readdir(dir))) {
+            const char* name = dp->d_name;
+            if (!strcmp(name, ".") || !strcmp(name, ".."))
+                continue;
+            char filePath[PATH_MAX];
+            if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
+                continue; // buffer overflow
+
+            auto string = stringFromFileSystemRepresentation(filePath);
+
+            // Some file system representations cannot be represented as a UTF-16 string,
+            // so this string might be null.
+            if (!string.isNull())
+                entries.append(WTFMove(string));
+        }
+        closedir(dir);
+    }
+    return entries;
+}
+
+} // namespace FileSystemImpl
+} // namespace WTF
+
+#endif // !HAVE(STD_FILESYSTEM) && !HAVE(STD_EXPERIMENTAL_FILESYSTEM)
</ins></span></pre></div>
<a id="trunkSourcecmakeOptionsCommoncmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/cmake/OptionsCommon.cmake (278026 => 278027)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/cmake/OptionsCommon.cmake   2021-05-25 17:25:44 UTC (rev 278026)
+++ trunk/Source/cmake/OptionsCommon.cmake      2021-05-25 17:34:01 UTC (rev 278027)
</span><span class="lines">@@ -161,7 +161,9 @@
</span><span class="cx">   SET_AND_EXPOSE_TO_BUILD(HAVE_INT128_T INT128_VALUE)
</span><span class="cx"> endif ()
</span><span class="cx"> 
</span><del>-# Check whether experimental/filesystem is the filesystem impl available
-if (STD_EXPERIMENTAL_FILESYSTEM_IS_AVAILABLE)
-  SET_AND_EXPOSE_TO_BUILD(HAVE_STD_EXPERIMENTAL_FILESYSTEM TRUE)
</del><ins>+# Check which filesystem implementation is available if any
+if (STD_FILESYSTEM_IS_AVAILABLE)
+    SET_AND_EXPOSE_TO_BUILD(HAVE_STD_FILESYSTEM TRUE)
+elseif (STD_EXPERIMENTAL_FILESYSTEM_IS_AVAILABLE)
+    SET_AND_EXPOSE_TO_BUILD(HAVE_STD_EXPERIMENTAL_FILESYSTEM TRUE)
</ins><span class="cx"> endif ()
</span></span></pre>
</div>
</div>

</body>
</html>