Fix build issues on old versions of iOS/MacOS.

-  I removed `std::filesystem` usages in the API definitions.
-  I stubbed out implementations that directly depend on `std::filesystem`.

I also did a few cosmetic changes to stubbing out the OSS glob implementation
for Windows/Android/Fuchsia.

Note that the FUZZTEST_STUB_STD_FILESYSTEM macro is currently defined in two
places. This is temporary and will be removed in the following CL.

PiperOrigin-RevId: 648452942
diff --git a/centipede/binary_info.cc b/centipede/binary_info.cc
index 2c2ba14..073e508 100644
--- a/centipede/binary_info.cc
+++ b/centipede/binary_info.cc
@@ -123,13 +123,14 @@
 void BinaryInfo::Read(std::string_view dir) {
   std::string symbol_table_contents;
   // TODO(b/295978603): move calculation of paths into WorkDir class.
-  RemoteFileGetContents(std::filesystem::path(dir).append(kSymbolTableFileName),
-                        symbol_table_contents);
+  RemoteFileGetContents(
+      (std::filesystem::path(dir) / kSymbolTableFileName).c_str(),
+      symbol_table_contents);
   std::istringstream symbol_table_stream(symbol_table_contents);
   symbols.ReadFromLLVMSymbolizer(symbol_table_stream);
 
   std::string pc_table_contents;
-  RemoteFileGetContents(std::filesystem::path(dir).append(kPCTableFileName),
+  RemoteFileGetContents((std::filesystem::path(dir) / kPCTableFileName).c_str(),
                         pc_table_contents);
   std::istringstream pc_table_stream(pc_table_contents);
   pc_table = ReadPcTable(pc_table_stream);
@@ -139,12 +140,13 @@
   std::ostringstream symbol_table_stream;
   symbols.WriteToLLVMSymbolizer(symbol_table_stream);
   // TODO(b/295978603): move calculation of paths into WorkDir class.
-  RemoteFileSetContents(std::filesystem::path(dir).append(kSymbolTableFileName),
-                        symbol_table_stream.str());
+  RemoteFileSetContents(
+      (std::filesystem::path(dir) / kSymbolTableFileName).c_str(),
+      symbol_table_stream.str());
 
   std::ostringstream pc_table_stream;
   WritePcTable(pc_table, pc_table_stream);
-  RemoteFileSetContents(std::filesystem::path(dir).append(kPCTableFileName),
+  RemoteFileSetContents((std::filesystem::path(dir) / kPCTableFileName).c_str(),
                         pc_table_stream.str());
 }
 
diff --git a/centipede/config_file.cc b/centipede/config_file.cc
index 6bc80b2..c03df11 100644
--- a/centipede/config_file.cc
+++ b/centipede/config_file.cc
@@ -162,7 +162,7 @@
   if (!path.empty() && !std::filesystem::exists(path)) {  // assume remote
     // Read the remote file.
     std::string contents;
-    RemoteFileGetContents(path, contents);
+    RemoteFileGetContents(path.c_str(), contents);
 
     // Save a temporary local copy.
     const std::filesystem::path tmp_dir = TemporaryLocalDirPath();
@@ -170,7 +170,7 @@
     LOG(INFO) << "Localizing remote config: " << VV(path) << VV(local_path);
     // NOTE: Ignore "Remote" in the API names here: the paths are always local.
     RemoteMkdir(tmp_dir.c_str());
-    RemoteFileSetContents(local_path, contents);
+    RemoteFileSetContents(local_path.c_str(), contents);
 
     // Augment the argv to point at the local copy and ensure it is cleaned up.
     replacements.emplace_back(path.c_str(), local_path.c_str());
@@ -244,7 +244,7 @@
     } else {
       file_contents = flags_str;
     }
-    RemoteFileSetContents(path, file_contents);
+    RemoteFileSetContents(path.c_str(), file_contents);
   }
 
   return path;
diff --git a/centipede/seed_corpus_maker_lib.cc b/centipede/seed_corpus_maker_lib.cc
index c35417e..b43d7e9 100644
--- a/centipede/seed_corpus_maker_lib.cc
+++ b/centipede/seed_corpus_maker_lib.cc
@@ -501,8 +501,9 @@
       /*my_shard_index=*/0,
   };
   const std::filesystem::path debug_info_dir = workdir.DebugInfoDirPath();
-  RemoteMkdir(debug_info_dir.string());
-  RemoteFileSetContents(debug_info_dir / "seeding.cfg", absl::StrCat(config));
+  RemoteMkdir(debug_info_dir.c_str());
+  RemoteFileSetContents((debug_info_dir / "seeding.cfg").c_str(),
+                        absl::StrCat(config));
 
   InputAndFeaturesVec elements;
 
diff --git a/centipede/util.cc b/centipede/util.cc
index cd972a2..ba33dac 100644
--- a/centipede/util.cc
+++ b/centipede/util.cc
@@ -146,7 +146,7 @@
 std::string HashOfFileContents(std::string_view file_path) {
   if (file_path.empty()) return "";
   std::string file_contents;
-  RemoteFileGetContents(std::filesystem::path(file_path), file_contents);
+  RemoteFileGetContents(file_path, file_contents);
   return Hash(file_contents);
 }
 
diff --git a/common/remote_file.cc b/common/remote_file.cc
index 63d95fc..eb761e6 100644
--- a/common/remote_file.cc
+++ b/common/remote_file.cc
@@ -17,8 +17,8 @@
 
 #include "./common/remote_file.h"
 
-#include <filesystem>  // NOLINT
 #include <string>
+#include <string_view>
 
 #include "absl/base/nullability.h"
 #include "absl/log/check.h"
@@ -39,33 +39,29 @@
   contents.assign(contents_ba.cbegin(), contents_ba.cend());
 }
 
-void RemoteFileSetContents(const std::filesystem::path &path,
-                           const ByteArray &contents) {
-  auto *file = RemoteFileOpen(path.string(), "w");
+void RemoteFileSetContents(std::string_view path, const ByteArray &contents) {
+  auto *file = RemoteFileOpen(path, "w");
   CHECK(file != nullptr) << VV(path);
   RemoteFileAppend(file, contents);
   RemoteFileClose(file);
 }
 
-void RemoteFileSetContents(const std::filesystem::path &path,
-                           const std::string &contents) {
-  auto *file = RemoteFileOpen(path.string(), "w");
+void RemoteFileSetContents(std::string_view path, const std::string &contents) {
+  auto *file = RemoteFileOpen(path, "w");
   CHECK(file != nullptr) << VV(path);
   RemoteFileAppend(file, contents);
   RemoteFileClose(file);
 }
 
-void RemoteFileGetContents(const std::filesystem::path &path,
-                           ByteArray &contents) {
-  auto *file = RemoteFileOpen(path.string(), "r");
+void RemoteFileGetContents(std::string_view path, ByteArray &contents) {
+  auto *file = RemoteFileOpen(path, "r");
   CHECK(file != nullptr) << VV(path);
   RemoteFileRead(file, contents);
   RemoteFileClose(file);
 }
 
-void RemoteFileGetContents(const std::filesystem::path &path,
-                           std::string &contents) {
-  auto *file = RemoteFileOpen(path.string(), "r");
+void RemoteFileGetContents(std::string_view path, std::string &contents) {
+  auto *file = RemoteFileOpen(path, "r");
   CHECK(file != nullptr) << VV(path);
   RemoteFileRead(file, contents);
   RemoteFileClose(file);
diff --git a/common/remote_file.h b/common/remote_file.h
index daf6a36..34e5d43 100644
--- a/common/remote_file.h
+++ b/common/remote_file.h
@@ -22,7 +22,6 @@
 
 #include <cstddef>
 #include <cstdint>
-#include <filesystem>  // NOLINT
 #include <memory>
 #include <string>
 #include <string_view>
@@ -35,6 +34,17 @@
 #include "riegeli/bytes/writer.h"
 #endif  // CENTIPEDE_DISABLE_RIEGELI
 
+#if defined(__APPLE__)
+#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&       \
+     __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_15) || \
+    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) &&      \
+     __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0)
+// std::filesystem requires macOS 10.15+ or iOS 13+.
+// Use this macro to stub out code that depends on std::filesystem.
+#define FUZZTEST_STUB_STD_FILESYSTEM
+#endif
+#endif
+
 namespace centipede {
 
 // An opaque file handle.
@@ -78,20 +88,16 @@
 void RemoteMkdir(std::string_view dir_path);
 
 // Sets the contents of the file at 'path' to 'contents'.
-void RemoteFileSetContents(const std::filesystem::path &path,
-                           const ByteArray &contents);
+void RemoteFileSetContents(std::string_view path, const ByteArray &contents);
 
 // Sets the contents of the file at 'path' to 'contents'.
-void RemoteFileSetContents(const std::filesystem::path &path,
-                           const std::string &contents);
+void RemoteFileSetContents(std::string_view path, const std::string &contents);
 
 // Reads the contents of the file at 'path' into 'contents'.
-void RemoteFileGetContents(const std::filesystem::path &path,
-                           ByteArray &contents);
+void RemoteFileGetContents(std::string_view path, ByteArray &contents);
 
 // Reads the contents of the file at 'path' into 'contents'.
-void RemoteFileGetContents(const std::filesystem::path &path,
-                           std::string &contents);
+void RemoteFileGetContents(std::string_view path, std::string &contents);
 
 // Returns true if `path` exists.
 bool RemotePathExists(std::string_view path);
diff --git a/common/remote_file_oss.cc b/common/remote_file_oss.cc
index 8229c35..826df7d 100644
--- a/common/remote_file_oss.cc
+++ b/common/remote_file_oss.cc
@@ -17,6 +17,7 @@
 
 #if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__Fuchsia__)
 #include <glob.h>
+#define FUZZTEST_HAS_OSS_GLOB
 #endif  // !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__Fuchsia__)
 
 #include <cstdint>
@@ -121,6 +122,31 @@
 
 }  // namespace
 
+#if defined(FUZZTEST_STUB_STD_FILESYSTEM)
+
+void RemoteMkdir(std::string_view path) {
+  LOG(FATAL) << "Filesystem API not supported in iOS/MacOS";
+}
+
+bool RemotePathExists(std::string_view path) {
+  LOG(FATAL) << "Filesystem API not supported in iOS/MacOS";
+}
+
+std::vector<std::string> RemoteListFiles(std::string_view path,
+                                         bool recursively) {
+  LOG(FATAL) << "Filesystem API not supported in iOS/MacOS";
+}
+
+void RemotePathRename(std::string_view from, std::string_view to) {
+  LOG(FATAL) << "Filesystem API not supported in iOS/MacOS";
+}
+
+void RemotePathDelete(std::string_view path, bool recursively) {
+  LOG(FATAL) << "Filesystem API not supported in iOS/MacOS";
+}
+
+#else
+
 void RemoteMkdir(std::string_view path) {
   CHECK(!path.empty());
   std::error_code error;
@@ -128,75 +154,10 @@
   CHECK(!error) << VV(path) << VV(error);
 }
 
-// TODO(ussuri): For now, simulate the old behavior, where a failure to open
-//  a file returned nullptr. Adjust the clients to expect non-null and use a
-//  normal ctor with a CHECK instead of `Create()` here instead.
-absl::Nullable<RemoteFile *> RemoteFileOpen(std::string_view path,
-                                            const char *mode) {
-  return LocalRemoteFile::Create(std::string(path), mode);
-}
-
-void RemoteFileClose(absl::Nonnull<RemoteFile *> f) {
-  auto *file = static_cast<LocalRemoteFile *>(f);
-  file->Close();
-  delete file;
-}
-
-void RemoteFileSetWriteBufferSize(absl::Nonnull<RemoteFile *> f, size_t size) {
-  static_cast<LocalRemoteFile *>(f)->SetWriteBufSize(size);
-}
-
-void RemoteFileAppend(absl::Nonnull<RemoteFile *> f, const ByteArray &ba) {
-  static_cast<LocalRemoteFile *>(f)->Write(ba);
-}
-
-void RemoteFileFlush(absl::Nonnull<RemoteFile *> f) {
-  static_cast<LocalRemoteFile *>(f)->Flush();
-}
-
-void RemoteFileRead(absl::Nonnull<RemoteFile *> f, ByteArray &ba) {
-  static_cast<LocalRemoteFile *>(f)->Read(ba);
-}
-
 bool RemotePathExists(std::string_view path) {
   return std::filesystem::exists(path);
 }
 
-int64_t RemoteFileGetSize(std::string_view path) {
-  FILE *f = std::fopen(path.data(), "r");
-  CHECK(f != nullptr) << VV(path);
-  std::fseek(f, 0, SEEK_END);
-  const auto sz = std::ftell(f);
-  std::fclose(f);
-  return sz;
-}
-
-namespace {
-
-int HandleGlobError(const char *epath, int eerrno) {
-  LOG(FATAL) << "Error while globbing path: " << VV(epath) << VV(eerrno);
-  return -1;
-}
-
-}  // namespace
-
-void RemoteGlobMatch(std::string_view glob, std::vector<std::string> &matches) {
-#if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__Fuchsia__)
-  // See `man glob.3`.
-  ::glob_t glob_ret = {};
-  CHECK_EQ(
-      ::glob(std::string{glob}.c_str(), GLOB_TILDE, HandleGlobError, &glob_ret),
-      0)
-      << "Error while globbing glob: " << VV(glob);
-  for (int i = 0; i < glob_ret.gl_pathc; ++i) {
-    matches.emplace_back(glob_ret.gl_pathv[i]);
-  }
-  ::globfree(&glob_ret);
-#else
-  LOG(FATAL) << __func__ << "() is not supported on this platform.";
-#endif  // !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__Fuchsia__)
-}
-
 std::vector<std::string> RemoteListFiles(std::string_view path,
                                          bool recursively) {
   if (!std::filesystem::exists(path)) return {};
@@ -231,6 +192,75 @@
   CHECK(!error) << VV(path) << VV(error);
 }
 
+#endif  // defined(FUZZTEST_STUB_STD_FILESYSTEM)
+
+// TODO(ussuri): For now, simulate the old behavior, where a failure to open
+//  a file returned nullptr. Adjust the clients to expect non-null and use a
+//  normal ctor with a CHECK instead of `Create()` here instead.
+absl::Nullable<RemoteFile *> RemoteFileOpen(std::string_view path,
+                                            const char *mode) {
+  return LocalRemoteFile::Create(std::string(path), mode);
+}
+
+void RemoteFileClose(absl::Nonnull<RemoteFile *> f) {
+  auto *file = static_cast<LocalRemoteFile *>(f);
+  file->Close();
+  delete file;
+}
+
+void RemoteFileSetWriteBufferSize(absl::Nonnull<RemoteFile *> f, size_t size) {
+  static_cast<LocalRemoteFile *>(f)->SetWriteBufSize(size);
+}
+
+void RemoteFileAppend(absl::Nonnull<RemoteFile *> f, const ByteArray &ba) {
+  static_cast<LocalRemoteFile *>(f)->Write(ba);
+}
+
+void RemoteFileFlush(absl::Nonnull<RemoteFile *> f) {
+  static_cast<LocalRemoteFile *>(f)->Flush();
+}
+
+void RemoteFileRead(absl::Nonnull<RemoteFile *> f, ByteArray &ba) {
+  static_cast<LocalRemoteFile *>(f)->Read(ba);
+}
+
+int64_t RemoteFileGetSize(std::string_view path) {
+  FILE *f = std::fopen(path.data(), "r");
+  CHECK(f != nullptr) << VV(path);
+  std::fseek(f, 0, SEEK_END);
+  const auto sz = std::ftell(f);
+  std::fclose(f);
+  return sz;
+}
+
+namespace {
+
+#if defined(FUZZTEST_HAS_OSS_GLOB)
+int HandleGlobError(const char *epath, int eerrno) {
+  LOG(FATAL) << "Error while globbing path: " << VV(epath) << VV(eerrno);
+  return -1;
+}
+#endif  // defined(FUZZTEST_HAS_OSS_GLOB)
+
+}  // namespace
+
+void RemoteGlobMatch(std::string_view glob, std::vector<std::string> &matches) {
+#if defined(FUZZTEST_HAS_OSS_GLOB)
+  // See `man glob.3`.
+  ::glob_t glob_ret = {};
+  CHECK_EQ(
+      ::glob(std::string{glob}.c_str(), GLOB_TILDE, HandleGlobError, &glob_ret),
+      0)
+      << "Error while globbing glob: " << VV(glob);
+  for (int i = 0; i < glob_ret.gl_pathc; ++i) {
+    matches.emplace_back(glob_ret.gl_pathv[i]);
+  }
+  ::globfree(&glob_ret);
+#else
+  LOG(FATAL) << __func__ << "() is not supported on this platform.";
+#endif  // defined(FUZZTEST_HAS_OSS_GLOB)
+}
+
 #ifndef CENTIPEDE_DISABLE_RIEGELI
 std::unique_ptr<riegeli::Reader> CreateRiegeliFileReader(
     std::string_view file_path) {
diff --git a/fuzztest/internal/io.cc b/fuzztest/internal/io.cc
index 864c2be..ef66cb4 100644
--- a/fuzztest/internal/io.cc
+++ b/fuzztest/internal/io.cc
@@ -15,9 +15,8 @@
 #include "./fuzztest/internal/io.h"
 
 #include <cerrno>
-#include <cstdio>
 #include <cstring>
-#include <filesystem>
+#include <filesystem>  // NOLINT
 #include <fstream>
 #include <optional>
 #include <sstream>
@@ -32,20 +31,21 @@
 #include "absl/strings/string_view.h"
 #include "./fuzztest/internal/logging.h"
 
+// TODO(fniksic): Remove this definition once we include remote_file.h.
 #if defined(__APPLE__)
 #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&       \
      __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_15) || \
     (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) &&      \
      __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0)
 // std::filesystem requires macOS 10.15+ or iOS 13+.
-// Just stub out these functions.
-#define FUZZTEST_STUB_FILESYSTEM
+// Use this macro to stub out code that depends on std::filesystem.
+#define FUZZTEST_STUB_STD_FILESYSTEM
 #endif
 #endif
 
 namespace fuzztest::internal {
 
-#if defined(FUZZTEST_STUB_FILESYSTEM)
+#if defined(FUZZTEST_STUB_STD_FILESYSTEM)
 
 // TODO(lszekeres): Return absl::Status instead of bool for these.
 
@@ -150,7 +150,7 @@
   return output_paths;
 }
 
-#endif  // FUZZTEST_STUB_FILESYSTEM
+#endif  // FUZZTEST_STUB_STD_FILESYSTEM
 
 std::string WriteDataToDir(absl::string_view data, absl::string_view outdir) {
   std::string filename(outdir);