diff --git a/base/files/file_util_starboard.cc b/base/files/file_util_starboard.cc index 83194f42dbbe..2181a01cf16b 100644 --- a/base/files/file_util_starboard.cc +++ b/base/files/file_util_starboard.cc @@ -16,6 +16,8 @@ #include "base/files/file_util.h" +#include + #include #include @@ -231,7 +233,8 @@ bool CopyFile(const FilePath &from_path, const FilePath &to_path) { bool PathExists(const FilePath &path) { AssertBlockingAllowed(); - return SbFileExists(path.value().c_str()); + struct stat file_info; + return stat(path.value().c_str(), &file_info) == 0; } bool PathIsWritable(const FilePath &path) { diff --git a/cobalt/browser/splash_screen_cache.cc b/cobalt/browser/splash_screen_cache.cc index 3e27fdfba7e1..0f5860326e50 100644 --- a/cobalt/browser/splash_screen_cache.cc +++ b/cobalt/browser/splash_screen_cache.cc @@ -14,6 +14,8 @@ #include "cobalt/browser/splash_screen_cache.h" +#include + #include #include #include @@ -101,7 +103,8 @@ bool SplashScreenCache::IsSplashScreenCached() const { if (!key) return false; std::string full_path = std::string(path.data()) + kSbFileSepString + key.value(); - return SbFileExists(full_path.c_str()); + struct stat file_info; + return stat(full_path.c_str(), &file_info) == 0; } int SplashScreenCache::ReadCachedSplashScreen( diff --git a/cobalt/browser/user_agent_string.cc b/cobalt/browser/user_agent_string.cc index bd4123172157..65bcf8413cc9 100644 --- a/cobalt/browser/user_agent_string.cc +++ b/cobalt/browser/user_agent_string.cc @@ -14,6 +14,10 @@ #include "cobalt/browser/user_agent_string.h" +#include +#include + +#include #include #include "base/command_line.h" @@ -21,6 +25,7 @@ #include "cobalt/browser/switches.h" #include "starboard/common/log.h" #include "starboard/common/string.h" +#include "starboard/log.h" #include "starboard/system.h" namespace cobalt { diff --git a/cobalt/site/docs/reference/starboard/configuration-public.md b/cobalt/site/docs/reference/starboard/configuration-public.md index 6c02fcecd6a0..fd2126bd732d 100644 --- a/cobalt/site/docs/reference/starboard/configuration-public.md +++ b/cobalt/site/docs/reference/starboard/configuration-public.md @@ -9,7 +9,6 @@ Book: /youtube/cobalt/_book.yaml | :--- | | **`SB_C_FORCE_INLINE`**

The platform's annotation for forcing a C function to be inlined.

The default value in the Stub implementation is
`__inline__ __attribute__((always_inline))` | | **`SB_C_INLINE`**

The platform's annotation for marking a C function as suggested to be inlined.

The default value in the Stub implementation is `inline` | -| **`SB_C_NOINLINE`**

The platform's annotation for marking a C function as forcibly not inlined.

The default value in the Stub implementation is `__attribute__((noinline))` | | **`SB_EXPORT_PLATFORM`**

The platform's annotation for marking a symbol as exported outside of the current shared library.

The default value in the Stub implementation is
`__attribute__((visibility("default")))` | | **`SB_IMPORT_PLATFORM`**

The platform's annotation for marking a symbol as imported from outside of the current linking unit. | diff --git a/cobalt/updater/utils.cc b/cobalt/updater/utils.cc index 05f3db198223..d2f85a9b05cf 100644 --- a/cobalt/updater/utils.cc +++ b/cobalt/updater/utils.cc @@ -4,6 +4,8 @@ #include "cobalt/updater/utils.h" +#include + #include #include @@ -100,10 +102,10 @@ const std::string GetEvergreenFileType(const std::string& installation_path) { {installation_path, kSbFileSepString, kCompressedLibraryPath}); std::string uncompressed_library_path = base::StrCat( {installation_path, kSbFileSepString, kUncompressedLibraryPath}); - - if (SbFileExists(compressed_library_path.c_str())) { + struct stat file_info; + if (stat(compressed_library_path.c_str(), &file_info) == 0) { return "Compressed"; - } else if (SbFileExists(uncompressed_library_path.c_str())) { + } else if (stat(uncompressed_library_path.c_str(), &file_info) == 0) { return "Uncompressed"; } else { LOG(ERROR) << "Failed to get Evergreen file type. Defaulting to " diff --git a/components/update_client/cobalt_slot_management.cc b/components/update_client/cobalt_slot_management.cc index 0014e67ebf85..afca1116849c 100644 --- a/components/update_client/cobalt_slot_management.cc +++ b/components/update_client/cobalt_slot_management.cc @@ -14,6 +14,8 @@ #include "components/update_client/cobalt_slot_management.h" +#include + #include #include @@ -33,11 +35,11 @@ bool CheckBadFileExists(const char* installation_path, const char* app_key) { std::string bad_app_key_file_path = starboard::loader_app::GetBadAppKeyFilePath(installation_path, app_key); SB_DCHECK(!bad_app_key_file_path.empty()); + struct stat file_info; + bool file_exists = stat(bad_app_key_file_path.c_str(), &file_info) == 0; LOG(INFO) << "bad_app_key_file_path: " << bad_app_key_file_path; - LOG(INFO) << "bad_app_key_file_path SbFileExists: " - << SbFileExists(bad_app_key_file_path.c_str()); - return !bad_app_key_file_path.empty() && - SbFileExists(bad_app_key_file_path.c_str()); + LOG(INFO) << "bad_app_key_file_path FileExists: " << file_exists; + return !bad_app_key_file_path.empty() && file_exists; } uint64_t ComputeSlotSize( @@ -324,18 +326,20 @@ bool CobaltQuickUpdate( std::string good_app_key_file_path = starboard::loader_app::GetGoodAppKeyFilePath( installation_dir.value().c_str(), app_key); + struct stat file_info; if (!installed_version.IsValid()) { LOG(WARNING) << "CobaltQuickInstallation: invalid version "; continue; } else if (slot_candidate_version < installed_version && current_version < installed_version && - (i == 0 || !DrainFileIsAnotherAppDraining( - installation_dir.value().c_str(), app_key) && - !CheckBadFileExists( - installation_dir.value().c_str(), app_key) && - !SbFileExists(good_app_key_file_path.c_str()) && - starboard::loader_app::AnyGoodAppKeyFile( - installation_dir.value().c_str()))) { + (i == 0 || + !DrainFileIsAnotherAppDraining(installation_dir.value().c_str(), + app_key) && + !CheckBadFileExists(installation_dir.value().c_str(), + app_key) && + stat(good_app_key_file_path.c_str(), &file_info) != 0 && + starboard::loader_app::AnyGoodAppKeyFile( + installation_dir.value().c_str()))) { // Found a slot with newer version than the current version. It's either // the system image slot, or a writeable installation slot that's not // draining, and no bad file of current app exists, and a good file diff --git a/components/update_client/cobalt_slot_management_test.cc b/components/update_client/cobalt_slot_management_test.cc index 5eac116a0ed0..6790005827a3 100644 --- a/components/update_client/cobalt_slot_management_test.cc +++ b/components/update_client/cobalt_slot_management_test.cc @@ -14,6 +14,8 @@ #include "components/update_client/cobalt_slot_management.h" +#include + #include #include @@ -238,9 +240,10 @@ TEST_F(CobaltSlotManagementTest, CobaltFinishInstallation) { ASSERT_EQ(IM_SUCCESS, ImRollForwardIfNeeded()); ASSERT_EQ(2, ImGetCurrentInstallationIndex()); - ASSERT_FALSE(SbFileExists(good_file_path.c_str())); + struct stat file_info; + ASSERT_FALSE(stat(good_file_path.c_str(), &file_info) == 0); ASSERT_TRUE(CobaltFinishInstallation(api_, 1, slot_path, kTestAppKey1)); - ASSERT_TRUE(SbFileExists(good_file_path.c_str())); + ASSERT_TRUE(stat(good_file_path.c_str(), &file_info) == 0); ASSERT_EQ(IM_SUCCESS, ImRollForwardIfNeeded()); ASSERT_EQ(1, ImGetCurrentInstallationIndex()); } diff --git a/docker/linux/base/build/Dockerfile b/docker/linux/base/build/Dockerfile index 8f08f7bc5a87..50d86ca9cba9 100644 --- a/docker/linux/base/build/Dockerfile +++ b/docker/linux/base/build/Dockerfile @@ -111,6 +111,18 @@ RUN cd /tmp \ && echo ${COBALT_CLANG_VER} >> ${COBALT_CLANG_TC_HOME}/cr_build_revision \ && rm clang-llvmorg-${COBALT_CLANG_VER}.tgz +# === Install Clang 16 toolchain for all Linux-hosted builds +ARG CLANG_16_TC_HOME=${TC_ROOT}/x86_64-linux-gnu-clang-chromium-16-init-17653-g39da55e8-2 +ARG CLANG_16_BASE_URL=https://commondatastorage.googleapis.com/chromium-browser-clang + +RUN cd /tmp \ + && mkdir -p ${CLANG_16_TC_HOME} \ + && curl --silent -O -J \ + ${CLANG_16_BASE_URL}/Linux_x64/clang-llvmorg-16-init-17653-g39da55e8-2.tgz \ + && tar xf clang-llvmorg-16-init-17653-g39da55e8-2.tgz -C ${CLANG_16_TC_HOME} \ + && echo 16-init-17653-g39da55e8-2 >> ${CLANG_16_TC_HOME}/cr_build_revision \ + && rm clang-llvmorg-16-init-17653-g39da55e8-2.tgz + RUN git config --global --add safe.directory /code WORKDIR /code diff --git a/starboard/CHANGELOG.md b/starboard/CHANGELOG.md index 1d125cb1bb9f..866dd399d647 100644 --- a/starboard/CHANGELOG.md +++ b/starboard/CHANGELOG.md @@ -9,6 +9,10 @@ since the version previous to it. ## Version 16 +## Removed `SB_C_NOINLINE` +This is only used for testing, a similar header is now found under +`starboard/shared/testing/no_inline.h` + ## Deprecated `OnScreenKeyboard` OnScreenKeyboard Starboard API has been deprecated, an extension in `starboard/extension/on_screen_keyboard.h` is available instead. The removal @@ -66,6 +70,10 @@ Build configurations for `SB_HAS_STD_UNORDERED_HASH`, `SB_HAS_LONG_LONG_HASH`, The standard API `getaddrinfo` and `freeaddrinfo`, can be used from . +### Added standard POSIX file stat API and deprecated SbFileExists. +The file API SbFileExists has been deprecated and the standard API `stat` can +be used from `sys/stat.h` instead. + ### Added standard POSIX socket send/recv APIs. The standard API `send`, `sendto`, `recv`, `recvfrom`, can be used from and `fcntl` can be used from , to set socket to non-blocking. diff --git a/starboard/android/shared/BUILD.gn b/starboard/android/shared/BUILD.gn index 3352d8ee4788..b4a21751a9fa 100644 --- a/starboard/android/shared/BUILD.gn +++ b/starboard/android/shared/BUILD.gn @@ -378,6 +378,7 @@ static_library("starboard_platform") { "player_set_max_video_input_size.cc", "player_set_max_video_input_size.h", "player_set_playback_rate.cc", + "posix_emu/stat.cc", "sanitizer_options.cc", "socket_get_interface_address.cc", "speech_synthesis_cancel.cc", diff --git a/starboard/android/shared/android_main.cc b/starboard/android/shared/android_main.cc index 29a4ee0ab53f..03a0ffe63bba 100644 --- a/starboard/android/shared/android_main.cc +++ b/starboard/android/shared/android_main.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include "game-activity/GameActivity.h" #include "starboard/android/shared/application_android.h" #include "starboard/android/shared/jni_env_ext.h" @@ -165,7 +167,8 @@ std::string ExtractCertificatesToFileSystem() { apk_path.append(std::string(kSbFileSepString) + "app" + kSbFileSepString + "cobalt" + kSbFileSepString + "content" + kSbFileSepString + "ssl" + kSbFileSepString + "certs"); - if (!SbFileExists(apk_path.c_str())) { + struct stat info; + if (stat(apk_path.c_str(), &info) != 0) { SB_LOG(WARNING) << "CA certificates directory not found in APK"; return ""; } diff --git a/starboard/android/shared/configuration_public.h b/starboard/android/shared/configuration_public.h index 3c1ebced4770..2f5055413866 100644 --- a/starboard/android/shared/configuration_public.h +++ b/starboard/android/shared/configuration_public.h @@ -58,10 +58,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/android/shared/file_exists.cc b/starboard/android/shared/file_exists.cc index cfe253c5db94..32dbd3afc5a8 100644 --- a/starboard/android/shared/file_exists.cc +++ b/starboard/android/shared/file_exists.cc @@ -12,8 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#if SB_API_VERSION < 16 #include "starboard/file.h" bool SbFileExists(const char* path) { return SbFileCanOpen(path, kSbFileRead); } +#endif diff --git a/starboard/android/shared/platform_configuration/BUILD.gn b/starboard/android/shared/platform_configuration/BUILD.gn index 1c626909f9f6..35671e87429b 100644 --- a/starboard/android/shared/platform_configuration/BUILD.gn +++ b/starboard/android/shared/platform_configuration/BUILD.gn @@ -162,6 +162,9 @@ config("platform_configuration") { # Wrapper synchronizes punch-out video bounds with the UI frame. "-Wl,--wrap=eglSwapBuffers", ] + if (!is_native_target_build) { + ldflags += [ "-Wl,--wrap=stat" ] + } } config("size") { diff --git a/starboard/android/shared/posix_emu/stat.cc b/starboard/android/shared/posix_emu/stat.cc new file mode 100644 index 000000000000..365bd5063562 --- /dev/null +++ b/starboard/android/shared/posix_emu/stat.cc @@ -0,0 +1,88 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include + +#include "starboard/android/shared/directory_internal.h" +#include "starboard/android/shared/file_internal.h" +#include "starboard/directory.h" + +using starboard::android::shared::IsAndroidAssetPath; +using starboard::android::shared::OpenAndroidAsset; + +/////////////////////////////////////////////////////////////////////////////// +// Implementations below exposed externally in pure C for emulation. +/////////////////////////////////////////////////////////////////////////////// + +extern "C" { +int __real_stat(const char* path, struct stat* info); + +// Reverse implementation of TimeTToWindowsUsec and PosixTimeToWindowsTime for +// backwards compatibility TimeTToWindowsUsec converts to microseconds +// (*1000000) and then calls PosixTimeToWindowsTime PosixTimeToWindows time adds +// number of microseconds since Jan 1, 1601 (UTC) until Jan 1, 1970 (UTC) +static SB_C_FORCE_INLINE time_t WindowsUsecToTimeTAndroid(int64_t time) { + int64_t posix_time = time - 11644473600000000ULL; + posix_time = posix_time / 1000000; + return posix_time; +} + +static void MapSbFileInfoToStat(SbFileInfo* file_info, struct stat* stat_info) { + stat_info->st_mode = 0; + if (file_info->is_directory) { + stat_info->st_mode = S_IFDIR; + } else if (file_info->is_symbolic_link) { + stat_info->st_mode = S_IFLNK; + } + + stat_info->st_ctime = WindowsUsecToTimeTAndroid(file_info->creation_time); + stat_info->st_atime = WindowsUsecToTimeTAndroid(file_info->last_accessed); + stat_info->st_mtime = WindowsUsecToTimeTAndroid(file_info->last_modified); + stat_info->st_size = file_info->size; +} + +// This needs to be exported to ensure shared_library targets include it. +int __wrap_stat(const char* path, struct stat* info) { + // SbFileExists(path) implementation for Android + if (!IsAndroidAssetPath(path)) { + return __real_stat(path, info); // Using system level stat call + } + + SbFile file = SbFileOpen(path, kSbFileRead | kSbFileOpenOnly, NULL, NULL); + SbFileInfo out_info; + if (file) { + bool result = SbFileGetInfo(file, &out_info); + MapSbFileInfoToStat(&out_info, info); + SbFileClose(file); + return 0; + } + + // Values from SbFileGetPathInfo + SbDirectory directory = SbDirectoryOpen(path, NULL); + if (directory && directory->asset_dir) { + info->st_mode = S_IFDIR; + info->st_ctime = 0; + info->st_atime = 0; + info->st_mtime = 0; + info->st_size = 0; + SbDirectoryClose(directory); + return 0; + } + + return -1; +} + +} // extern "C" diff --git a/starboard/android/shared/test_filters.py b/starboard/android/shared/test_filters.py index 39274720f7a1..7c90f5484614 100644 --- a/starboard/android/shared/test_filters.py +++ b/starboard/android/shared/test_filters.py @@ -60,6 +60,10 @@ 'SbDirectoryGetNextTest.SunnyDayStaticContent', 'SbDirectoryOpenTest.SunnyDayStaticContent', 'SbFileGetPathInfoTest.WorksOnStaticContentDirectories', + 'PosixDirectoryCanOpenTest.SunnyDayStaticContent', + 'PosixDirectoryGetNextTest.SunnyDayStaticContent', + 'PosixDirectoryOpenTest.SunnyDayStaticContent', + 'PosixFileGetPathInfoTest.WorksOnStaticContentDirectories', # These tests are disabled due to not receiving the kEndOfStream # player state update within the specified timeout. diff --git a/starboard/common/file.cc b/starboard/common/file.cc index e2aa87787e19..3dc007e761e2 100644 --- a/starboard/common/file.cc +++ b/starboard/common/file.cc @@ -14,6 +14,8 @@ #include "starboard/common/file.h" +#include + #include #include #include @@ -49,7 +51,8 @@ void RecordFileWriteStat(int write_file_result) { } bool SbFileDeleteRecursive(const char* path, bool preserve_root) { - if (!SbFileExists(path)) { + struct stat file_info; + if (stat(path, &file_info) != 0) { SB_LOG(ERROR) << "Path does not exist: '" << path << "'"; return false; } diff --git a/starboard/common/paths.cc b/starboard/common/paths.cc index 3ebbfc52db02..ef44eb3d4853 100644 --- a/starboard/common/paths.cc +++ b/starboard/common/paths.cc @@ -14,9 +14,10 @@ #include "starboard/common/paths.h" +#include + #include #include - #include "starboard/common/log.h" #include "starboard/configuration_constants.h" #include "starboard/file.h" @@ -70,9 +71,10 @@ std::string GetCACertificatesPath(const std::string& content_subdir) { return ""; } + struct stat info; std::string ca_certificates_path = GetCACertificatesPathFromSubdir(content_subdir); - if (!SbFileExists(ca_certificates_path.c_str())) { + if (stat(ca_certificates_path.c_str(), &info) != 0) { SB_LOG(ERROR) << "Failed to get CA certificates path"; return ""; } @@ -87,12 +89,13 @@ std::string GetCACertificatesPath() { std::string ca_certificates_path = GetCACertificatesPathFromSubdir(content_subdir); + struct stat info; // Then fall back to the regular content path if necessary. - if (!SbFileExists(ca_certificates_path.c_str())) { + if (stat(ca_certificates_path.c_str(), &info) != 0) { ca_certificates_path = GetCACertificatesPathFromSubdir(""); } - if (!SbFileExists(ca_certificates_path.c_str())) { + if (stat(ca_certificates_path.c_str(), &info) != 0) { SB_LOG(ERROR) << "Failed to get CA certificates path"; return ""; } diff --git a/starboard/elf_loader/exported_symbols.cc b/starboard/elf_loader/exported_symbols.cc index a537c4eea2e8..2e44a7102d59 100644 --- a/starboard/elf_loader/exported_symbols.cc +++ b/starboard/elf_loader/exported_symbols.cc @@ -51,6 +51,7 @@ #if SB_API_VERSION >= 16 #include "starboard/shared/modular/starboard_layer_posix_mmap_abi_wrappers.h" #include "starboard/shared/modular/starboard_layer_posix_pthread_abi_wrappers.h" +#include "starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h" #include "starboard/shared/modular/starboard_layer_posix_time_abi_wrappers.h" #endif // SB_API_VERSION >= 16 #include "starboard/socket.h" @@ -159,7 +160,9 @@ ExportedSymbols::ExportedSymbols() { REGISTER_SYMBOL(SbFileCanOpen); REGISTER_SYMBOL(SbFileClose); REGISTER_SYMBOL(SbFileDelete); +#if SB_API_VERSION < 16 REGISTER_SYMBOL(SbFileExists); +#endif // SB_API_VERSION < 16 REGISTER_SYMBOL(SbFileFlush); REGISTER_SYMBOL(SbFileGetInfo); REGISTER_SYMBOL(SbFileGetPathInfo); @@ -499,6 +502,7 @@ ExportedSymbols::ExportedSymbols() { reinterpret_cast(&__abi_wrap_pthread_mutex_trylock); map_["pthread_once"] = reinterpret_cast(&__abi_wrap_pthread_once); + map_["stat"] = reinterpret_cast(&__abi_wrap_stat); map_["time"] = reinterpret_cast(&__abi_wrap_time); #if defined(_MSC_VER) diff --git a/starboard/evergreen/arm/hardfp/configuration_public.h b/starboard/evergreen/arm/hardfp/configuration_public.h index bf27adea7f99..590eb418d38d 100644 --- a/starboard/evergreen/arm/hardfp/configuration_public.h +++ b/starboard/evergreen/arm/hardfp/configuration_public.h @@ -56,10 +56,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/evergreen/arm/softfp/configuration_public.h b/starboard/evergreen/arm/softfp/configuration_public.h index 5d85c23440ab..6c39074fea42 100644 --- a/starboard/evergreen/arm/softfp/configuration_public.h +++ b/starboard/evergreen/arm/softfp/configuration_public.h @@ -56,10 +56,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/evergreen/arm64/configuration_public.h b/starboard/evergreen/arm64/configuration_public.h index da64cd6466f3..ce7c45157c99 100644 --- a/starboard/evergreen/arm64/configuration_public.h +++ b/starboard/evergreen/arm64/configuration_public.h @@ -56,10 +56,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/evergreen/x64/configuration_public.h b/starboard/evergreen/x64/configuration_public.h index ffd5efde0a7d..d0e34d80d8f7 100644 --- a/starboard/evergreen/x64/configuration_public.h +++ b/starboard/evergreen/x64/configuration_public.h @@ -56,10 +56,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/evergreen/x86/configuration_public.h b/starboard/evergreen/x86/configuration_public.h index 5f22ed70806a..05d1b0a3e175 100644 --- a/starboard/evergreen/x86/configuration_public.h +++ b/starboard/evergreen/x86/configuration_public.h @@ -56,10 +56,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/file.h b/starboard/file.h index dcb9ff4a07e9..8ca3e90b1714 100644 --- a/starboard/file.h +++ b/starboard/file.h @@ -244,10 +244,12 @@ SB_EXPORT bool SbFileGetPathInfo(const char* path, SbFileInfo* out_info); // |path|: The absolute path of the file, symlink, or directory to be deleted. SB_EXPORT bool SbFileDelete(const char* path); +#if SB_API_VERSION < 16 // Indicates whether a file or directory exists at |path|. // // |path|: The absolute path of the file or directory being checked. SB_EXPORT bool SbFileExists(const char* path); +#endif // SB_API_VERSION < 16 // Indicates whether SbFileOpen() with the given |flags| is allowed for |path|. // diff --git a/starboard/linux/shared/configuration_public.h b/starboard/linux/shared/configuration_public.h index 35c31b10bdc3..8b331bdd0d5f 100644 --- a/starboard/linux/shared/configuration_public.h +++ b/starboard/linux/shared/configuration_public.h @@ -58,10 +58,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/loader_app/app_key_files_test.cc b/starboard/loader_app/app_key_files_test.cc index 06df41c5cc23..747de1f75e25 100644 --- a/starboard/loader_app/app_key_files_test.cc +++ b/starboard/loader_app/app_key_files_test.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/app_key_files.h" +#include + #include #include @@ -39,30 +41,35 @@ class AppKeyFilesTest : public testing::Test { SbDirectoryCreate(dir_.c_str()); } + bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; + } + std::string dir_; }; TEST_F(AppKeyFilesTest, TestGoodKeyFile) { std::string file_path = GetGoodAppKeyFilePath(dir_, kTestAppKey); ASSERT_FALSE(file_path.empty()); - if (SbFileExists(file_path.c_str())) { + if (FileExists(file_path.c_str())) { SbFileDelete(file_path.c_str()); } - ASSERT_FALSE(SbFileExists(file_path.c_str())); + ASSERT_FALSE(FileExists(file_path.c_str())); ASSERT_TRUE(CreateAppKeyFile(file_path)); - ASSERT_TRUE(SbFileExists(file_path.c_str())); + ASSERT_TRUE(FileExists(file_path.c_str())); SbFileDelete(file_path.c_str()); } TEST_F(AppKeyFilesTest, TestBadKeyFile) { std::string file_path = GetBadAppKeyFilePath(dir_, kTestAppKey); ASSERT_FALSE(file_path.empty()); - if (SbFileExists(file_path.c_str())) { + if (FileExists(file_path.c_str())) { SbFileDelete(file_path.c_str()); } - ASSERT_FALSE(SbFileExists(file_path.c_str())); + ASSERT_FALSE(FileExists(file_path.c_str())); ASSERT_TRUE(CreateAppKeyFile(file_path)); - ASSERT_TRUE(SbFileExists(file_path.c_str())); + ASSERT_TRUE(FileExists(file_path.c_str())); SbFileDelete(file_path.c_str()); } @@ -87,7 +94,7 @@ TEST_F(AppKeyFilesTest, TestAnyGoodKeyFile) { std::string file_path = GetGoodAppKeyFilePath(dir_, kTestAppKey); ASSERT_FALSE(file_path.empty()); ASSERT_TRUE(CreateAppKeyFile(file_path)); - ASSERT_TRUE(SbFileExists(file_path.c_str())); + ASSERT_TRUE(FileExists(file_path.c_str())); ASSERT_TRUE(AnyGoodAppKeyFile(dir_)); SbFileDelete(file_path.c_str()); } diff --git a/starboard/loader_app/drain_file_helper.cc b/starboard/loader_app/drain_file_helper.cc index 7ce262f45fa1..a0f36227f0ec 100644 --- a/starboard/loader_app/drain_file_helper.cc +++ b/starboard/loader_app/drain_file_helper.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/drain_file_helper.h" +#include + #include "starboard/common/file.h" #include "starboard/loader_app/drain_file.h" #include "testing/gtest/include/gtest/gtest.h" @@ -43,7 +45,8 @@ ScopedDrainFile::~ScopedDrainFile() { } bool ScopedDrainFile::Exists() const { - return SbFileExists(path_.c_str()); + struct stat info; + return stat(path_.c_str(), &info) == 0; } const std::string& ScopedDrainFile::app_key() const { diff --git a/starboard/loader_app/drain_file_test.cc b/starboard/loader_app/drain_file_test.cc index d9b01fdfad63..3dc393d0d7ec 100644 --- a/starboard/loader_app/drain_file_test.cc +++ b/starboard/loader_app/drain_file_test.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/drain_file.h" +#include + #include #include @@ -53,6 +55,11 @@ class DrainFileTest : public ::testing::Test { const char* GetTempDir() const { return temp_dir_.data(); } + bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; + } + private: std::vector temp_dir_; }; @@ -129,11 +136,11 @@ TEST_F(DrainFileTest, SunnyDayClearExpired) { EXPECT_TRUE(DrainFileIsAppDraining(GetTempDir(), kAppKeyOne)); EXPECT_TRUE(DrainFileIsAppDraining(GetTempDir(), kAppKeyTwo)); - EXPECT_TRUE(SbFileExists(stale_file.path().c_str())); + EXPECT_TRUE(FileExists(stale_file.path().c_str())); DrainFileClearExpired(GetTempDir()); - EXPECT_FALSE(SbFileExists(stale_file.path().c_str())); + EXPECT_FALSE(FileExists(stale_file.path().c_str())); } // Clearing drain files for an app. @@ -148,14 +155,14 @@ TEST_F(DrainFileTest, SunnyDayClearForApp) { EXPECT_TRUE(DrainFileIsAppDraining(GetTempDir(), kAppKeyOne)); EXPECT_TRUE(DrainFileIsAppDraining(GetTempDir(), kAppKeyTwo)); - EXPECT_TRUE(SbFileExists(stale_file.path().c_str())); + EXPECT_TRUE(FileExists(stale_file.path().c_str())); // clean all drain files for an app DrainFileClearForApp(GetTempDir(), kAppKeyOne); EXPECT_FALSE(DrainFileIsAppDraining(GetTempDir(), kAppKeyOne)); EXPECT_TRUE(DrainFileIsAppDraining(GetTempDir(), kAppKeyTwo)); - EXPECT_TRUE(SbFileExists(stale_file.path().c_str())); + EXPECT_TRUE(FileExists(stale_file.path().c_str())); } // Ranking drain files should first be done by timestamp, with the app key being @@ -224,7 +231,7 @@ TEST_F(DrainFileTest, SunnyDayPrepareDirectory) { dir.append("to_delete"); EXPECT_TRUE(SbDirectoryCreate(dir.c_str())); - EXPECT_TRUE(SbFileExists(dir.c_str())); + EXPECT_TRUE(FileExists(dir.c_str())); // Create a file with the app key in the name. std::string path(GetTempDir()); @@ -235,13 +242,13 @@ TEST_F(DrainFileTest, SunnyDayPrepareDirectory) { ScopedFile file(path.c_str(), kSbFileOpenAlways | kSbFileWrite, NULL, NULL); } - EXPECT_TRUE(SbFileExists(path.c_str())); + EXPECT_TRUE(FileExists(path.c_str())); DrainFilePrepareDirectory(GetTempDir(), kAppKeyOne); EXPECT_TRUE(DrainFileRankAndCheck(GetTempDir(), kAppKeyOne)); - EXPECT_FALSE(SbFileExists(dir.c_str())); - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(dir.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); DrainFilePrepareDirectory(GetTempDir(), "nonexistent"); diff --git a/starboard/loader_app/installation_manager_test.cc b/starboard/loader_app/installation_manager_test.cc index d8cdc58642cf..15a05458faa3 100644 --- a/starboard/loader_app/installation_manager_test.cc +++ b/starboard/loader_app/installation_manager_test.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/installation_manager.h" +#include + #include #include @@ -165,6 +167,11 @@ class InstallationManagerTest : public ::testing::TestWithParam { } } + bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; + } + virtual void TearDown() { if (!storage_path_implemented_) { return; @@ -233,13 +240,13 @@ TEST_P(InstallationManagerTest, Reset) { ASSERT_EQ(IM_SUCCESS, ImReset()); ASSERT_EQ(0, ImGetCurrentInstallationIndex()); for (auto& f : created_files) { - ASSERT_TRUE(!SbFileExists(f.c_str())); + ASSERT_TRUE(!FileExists(f.c_str())); } for (int i = 1; i < max_num_installations - 1; i++) { std::vector buf(kSbFileMaxPath); ASSERT_EQ(IM_INSTALLATION_STATUS_NOT_SUCCESS, ImGetInstallationStatus(i)); ASSERT_EQ(IM_SUCCESS, ImGetInstallationPath(i, buf.data(), kSbFileMaxPath)); - ASSERT_TRUE(SbFileExists(buf.data())); + ASSERT_TRUE(FileExists(buf.data())); } } @@ -325,7 +332,7 @@ TEST_P(InstallationManagerTest, GetInstallationPath) { ASSERT_EQ(IM_SUCCESS, ImGetInstallationPath(0, buf0.data(), kSbFileMaxPath)); std::vector buf1(kSbFileMaxPath); ASSERT_EQ(IM_SUCCESS, ImGetInstallationPath(1, buf1.data(), kSbFileMaxPath)); - ASSERT_TRUE(SbFileExists(buf1.data())); + ASSERT_TRUE(FileExists(buf1.data())); } TEST_P(InstallationManagerTest, RollForwardIfNeeded) { diff --git a/starboard/loader_app/loader_app.cc b/starboard/loader_app/loader_app.cc index 93cf9f4e6ec3..9ff56b14c50b 100644 --- a/starboard/loader_app/loader_app.cc +++ b/starboard/loader_app/loader_app.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include "cobalt/version.h" @@ -111,10 +113,11 @@ void LoadLibraryAndInitialize(const std::string& alternative_content_path, uncompressed_library_path += kSystemImageLibraryPath; bool use_compression; - if (SbFileExists(compressed_library_path.c_str())) { + struct stat info; + if (stat(compressed_library_path.c_str(), &info) == 0) { library_path = compressed_library_path; use_compression = true; - } else if (SbFileExists(uncompressed_library_path.c_str())) { + } else if (stat(uncompressed_library_path.c_str(), &info) == 0) { library_path = uncompressed_library_path; use_compression = false; } else { diff --git a/starboard/loader_app/reset_evergreen_update_test.cc b/starboard/loader_app/reset_evergreen_update_test.cc index d007fb62132c..9f34f95dcc4c 100644 --- a/starboard/loader_app/reset_evergreen_update_test.cc +++ b/starboard/loader_app/reset_evergreen_update_test.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/reset_evergreen_update.h" +#include + #include #include @@ -27,6 +29,11 @@ namespace starboard { namespace loader_app { namespace { +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(ResetEvergreenUpdateTest, TestSunnyDayFile) { std::vector storage_path(kSbFileMaxPath); ASSERT_TRUE(SbSystemGetPath(kSbSystemPathStorageDirectory, @@ -46,12 +53,12 @@ TEST(ResetEvergreenUpdateTest, TestSunnyDayFile) { int bytes_written = file.WriteAll(data.c_str(), data.size()); } - ASSERT_TRUE(SbFileExists(file_path.data())); + ASSERT_TRUE(FileExists(file_path.data())); ASSERT_TRUE(ResetEvergreenUpdate()); - ASSERT_FALSE(SbFileExists(file_path.data())); - ASSERT_TRUE(SbFileExists(storage_path.data())); + ASSERT_FALSE(FileExists(file_path.data())); + ASSERT_TRUE(FileExists(storage_path.data())); } TEST(ResetEvergreenUpdateTest, TestSunnyDaySubdir) { @@ -78,12 +85,12 @@ TEST(ResetEvergreenUpdateTest, TestSunnyDaySubdir) { int bytes_written = file.WriteAll(data.c_str(), data.size()); } - ASSERT_TRUE(SbFileExists(file_path.data())); + ASSERT_TRUE(FileExists(file_path.data())); ASSERT_TRUE(ResetEvergreenUpdate()); - ASSERT_FALSE(SbFileExists(file_path.data())); - ASSERT_TRUE(SbFileExists(storage_path.data())); + ASSERT_FALSE(FileExists(file_path.data())); + ASSERT_TRUE(FileExists(storage_path.data())); } } // namespace } // namespace loader_app diff --git a/starboard/loader_app/slot_management.cc b/starboard/loader_app/slot_management.cc index ab02b9177883..580d256b1ef8 100644 --- a/starboard/loader_app/slot_management.cc +++ b/starboard/loader_app/slot_management.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/slot_management.h" +#include + #include #include "starboard/common/log.h" @@ -88,11 +90,11 @@ bool CheckBadFileExists(const char* installation_path, const char* app_key) { std::string bad_app_key_file_path = starboard::loader_app::GetBadAppKeyFilePath(installation_path, app_key); SB_DCHECK(!bad_app_key_file_path.empty()); + struct stat info; + bool file_exists = stat(bad_app_key_file_path.c_str(), &info) == 0; SB_LOG(INFO) << "bad_app_key_file_path: " << bad_app_key_file_path; - SB_LOG(INFO) << "bad_app_key_file_path SbFileExists: " - << SbFileExists(bad_app_key_file_path.c_str()); - return !bad_app_key_file_path.empty() && - SbFileExists(bad_app_key_file_path.c_str()); + SB_LOG(INFO) << "bad_app_key_file_path FileExists: " << file_exists; + return !bad_app_key_file_path.empty() && file_exists; } bool AdoptInstallation(int current_installation, @@ -114,8 +116,8 @@ bool AdoptInstallation(int current_installation, << app_key; return false; } - - if (!SbFileExists(good_app_key_file_path.c_str())) { + struct stat info; + if (stat(good_app_key_file_path.c_str(), &info) != 0) { if (!starboard::loader_app::CreateAppKeyFile(good_app_key_file_path)) { SB_LOG(WARNING) << "Failed to create good app key file"; return false; @@ -233,10 +235,11 @@ void* LoadSlotManagedLibrary(const std::string& app_key, std::string lib_path; bool use_compression; - if (SbFileExists(compressed_lib_path.data())) { + struct stat info; + if (stat(compressed_lib_path.data(), &info) == 0) { lib_path = compressed_lib_path.data(); use_compression = true; - } else if (SbFileExists(uncompressed_lib_path.data())) { + } else if (stat(uncompressed_lib_path.data(), &info) == 0) { lib_path = uncompressed_lib_path.data(); use_compression = false; } else { diff --git a/starboard/loader_app/slot_management_test.cc b/starboard/loader_app/slot_management_test.cc index 1c59aa565089..cf6f819ad088 100644 --- a/starboard/loader_app/slot_management_test.cc +++ b/starboard/loader_app/slot_management_test.cc @@ -14,6 +14,8 @@ #include "starboard/loader_app/slot_management.h" +#include + #include #include @@ -92,6 +94,11 @@ class SlotManagementTest : public testing::TestWithParam { return result; } + bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; + } + void CreateBadFile(int index, const std::string& app_key) { std::vector installation_path(kSbFileMaxPath); ASSERT_EQ(IM_SUCCESS, ImGetInstallationPath(index, installation_path.data(), @@ -122,7 +129,7 @@ class SlotManagementTest : public testing::TestWithParam { starboard::loader_app::GetGoodAppKeyFilePath(installation_path.data(), app_key); ASSERT_TRUE(!good_app_key_file_path.empty()); - ASSERT_EQ(exists, SbFileExists(good_app_key_file_path.c_str())); + ASSERT_EQ(exists, FileExists(good_app_key_file_path.c_str())); } void VerifyBadFile(int index, const std::string& app_key, bool exists) { @@ -133,7 +140,7 @@ class SlotManagementTest : public testing::TestWithParam { app_key); ASSERT_TRUE(!bad_app_key_file_path.empty()); SB_LOG(INFO) << "bad_app_key_file_path=" << bad_app_key_file_path; - ASSERT_EQ(exists, SbFileExists(bad_app_key_file_path.c_str())); + ASSERT_EQ(exists, FileExists(bad_app_key_file_path.c_str())); } void CreateDrainFile(int index, const std::string& app_key) { @@ -176,7 +183,7 @@ class SlotManagementTest : public testing::TestWithParam { for (const std::string& dir : dirs) { path += kSbFileSepString; path += dir; - if (!SbFileExists(path.c_str())) { + if (!FileExists(path.c_str())) { EXPECT_TRUE(SbDirectoryCreate(path.c_str())); if (out_top_created_dir.empty()) { diff --git a/starboard/nplb/BUILD.gn b/starboard/nplb/BUILD.gn index 2827b8636049..4f2fc8052afe 100644 --- a/starboard/nplb/BUILD.gn +++ b/starboard/nplb/BUILD.gn @@ -141,7 +141,9 @@ target(gtest_target_type, "nplb") { "posix_compliance/posix_condition_variable_signal_test.cc", "posix_compliance/posix_condition_variable_wait_test.cc", "posix_compliance/posix_condition_variable_wait_timed_test.cc", + "posix_compliance/posix_directory_can_open_test.cc", "posix_compliance/posix_file_close_test.cc", + "posix_compliance/posix_file_get_path_info_test.cc", "posix_compliance/posix_file_open_test.cc", "posix_compliance/posix_memory_allocate_aligned_test.cc", "posix_compliance/posix_memory_allocate_test.cc", diff --git a/starboard/nplb/directory_can_open_test.cc b/starboard/nplb/directory_can_open_test.cc index f2cb844a9916..178d059903b5 100644 --- a/starboard/nplb/directory_can_open_test.cc +++ b/starboard/nplb/directory_can_open_test.cc @@ -23,6 +23,7 @@ namespace starboard { namespace nplb { namespace { +#if SB_API_VERSION < 16 TEST(SbDirectoryCanOpenTest, SunnyDay) { std::string path = starboard::nplb::GetTempDir(); EXPECT_FALSE(path.empty()); @@ -30,6 +31,7 @@ TEST(SbDirectoryCanOpenTest, SunnyDay) { EXPECT_TRUE(SbDirectoryCanOpen(path.c_str())); } +#endif TEST(SbDirectoryCanOpenTest, SunnyDayStaticContent) { for (auto dir_path : GetFileTestsDirectoryPaths()) { @@ -52,12 +54,14 @@ TEST(SbDirectoryCanOpenTest, FailureEmpty) { EXPECT_FALSE(SbDirectoryCanOpen("")); } +#if SB_API_VERSION < 16 TEST(SbDirectoryCanOpenTest, FailureRegularFile) { starboard::nplb::ScopedRandomFile file; EXPECT_TRUE(SbFileExists(file.filename().c_str())); EXPECT_FALSE(SbDirectoryCanOpen(file.filename().c_str())); } +#endif // SB_API_VERSION < 16 } // namespace } // namespace nplb diff --git a/starboard/nplb/directory_get_next_test.cc b/starboard/nplb/directory_get_next_test.cc index ea3a74f188c0..323cfbeb52b4 100644 --- a/starboard/nplb/directory_get_next_test.cc +++ b/starboard/nplb/directory_get_next_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include #include @@ -29,13 +31,18 @@ namespace { typedef std::set StringSet; +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(SbDirectoryGetNextTest, SunnyDay) { const int kNumFiles = 65; ScopedRandomFile files[kNumFiles]; std::string directory_name = files[0].filename(); directory_name.resize(directory_name.find_last_of(kSbFileSepChar)); - EXPECT_TRUE(SbFileExists(directory_name.c_str())) + EXPECT_TRUE(FileExists(directory_name.c_str())) << "Missing directory: " << directory_name; SbFileError error = kSbFileErrorMax; @@ -83,7 +90,7 @@ TEST(SbDirectoryGetNextTest, SunnyDay) { TEST(SbDirectoryGetNextTest, SunnyDayStaticContent) { std::string testdata_dir = GetFileTestsDataDir(); EXPECT_FALSE(testdata_dir.empty()); - EXPECT_TRUE(SbFileExists(testdata_dir.c_str())) + EXPECT_TRUE(FileExists(testdata_dir.c_str())) << "Missing directory: " << testdata_dir; // Make sure all the test directories and files are found exactly once. @@ -160,7 +167,7 @@ TEST(SbDirectoryGetNextTest, FailureNullEntry) { std::string path = GetTempDir(); EXPECT_FALSE(path.empty()); - EXPECT_TRUE(SbFileExists(path.c_str())) << "Directory is " << path; + EXPECT_TRUE(FileExists(path.c_str())) << "Directory is " << path; SbFileError error = kSbFileErrorMax; SbDirectory directory = SbDirectoryOpen(path.c_str(), &error); @@ -178,7 +185,7 @@ TEST(SbDirectoryGetNextTest, FailureOnInsufficientSize) { ScopedRandomFile file; std::string directory_name = file.filename(); directory_name.resize(directory_name.find_last_of(kSbFileSepChar)); - EXPECT_TRUE(SbFileExists(directory_name.c_str())) + EXPECT_TRUE(FileExists(directory_name.c_str())) << "Directory_name is " << directory_name; SbFileError error = kSbFileErrorMax; diff --git a/starboard/nplb/directory_open_test.cc b/starboard/nplb/directory_open_test.cc index 0eb10be98d47..ee0ee97ab210 100644 --- a/starboard/nplb/directory_open_test.cc +++ b/starboard/nplb/directory_open_test.cc @@ -25,6 +25,7 @@ namespace starboard { namespace nplb { namespace { +#if SB_API_VERSION < 16 #define EXPECT_FILE_EXISTS(path) \ EXPECT_TRUE(SbFileExists(path.c_str())) << "Filename is " << path.c_str() @@ -39,6 +40,7 @@ TEST(SbDirectoryOpenTest, SunnyDay) { EXPECT_EQ(kSbFileOk, error); EXPECT_TRUE(SbDirectoryClose(directory)); } +#endif TEST(SbDirectoryOpenTest, SunnyDayStaticContent) { for (auto dir_path : GetFileTestsDirectoryPaths()) { @@ -50,6 +52,7 @@ TEST(SbDirectoryOpenTest, SunnyDayStaticContent) { } } +#if SB_API_VERSION < 16 TEST(SbDirectoryOpenTest, SunnyDayWithNullError) { std::string path = GetTempDir(); EXPECT_FALSE(path.empty()); @@ -103,6 +106,7 @@ TEST(SbDirectoryOpenTest, FailsInvalidPath) { SbDirectoryClose(directory); } } +#endif TEST(SbDirectoryOpenTest, FailsNullPath) { SbFileError error = kSbFileErrorMax; diff --git a/starboard/nplb/file_atomic_replace_test.cc b/starboard/nplb/file_atomic_replace_test.cc index 7c99afeeb2e3..c13330b41035 100644 --- a/starboard/nplb/file_atomic_replace_test.cc +++ b/starboard/nplb/file_atomic_replace_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include "starboard/file.h" #include "starboard/nplb/file_helpers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,12 +46,17 @@ bool CompareFileContentsToString(const char* filename, return strncmp(str, result, kTestContentsLength) == 0; } +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(SbFileAtomicReplaceTest, ReplacesValidFile) { ScopedRandomFile random_file(ScopedRandomFile::kDefaultLength, ScopedRandomFile::kCreate); const std::string& filename = random_file.filename(); - EXPECT_TRUE(SbFileExists(filename.c_str())); + EXPECT_TRUE(FileExists(filename.c_str())); EXPECT_TRUE(SbFileAtomicReplace(filename.c_str(), kTestContents, kTestContentsLength)); EXPECT_TRUE(CompareFileContentsToString(filename.c_str(), kTestContents, @@ -60,7 +67,7 @@ TEST(SbFileAtomicReplaceTest, ReplacesNonExistentFile) { ScopedRandomFile random_file(ScopedRandomFile::kDontCreate); const std::string& filename = random_file.filename(); - EXPECT_FALSE(SbFileExists(filename.c_str())); + EXPECT_FALSE(FileExists(filename.c_str())); EXPECT_TRUE(SbFileAtomicReplace(filename.c_str(), kTestContents, kTestContentsLength)); EXPECT_TRUE(CompareFileContentsToString(filename.c_str(), kTestContents, @@ -71,7 +78,7 @@ TEST(SbFileAtomicReplaceTest, ReplacesWithNoData) { ScopedRandomFile random_file(ScopedRandomFile::kCreate); const std::string& filename = random_file.filename(); - EXPECT_TRUE(SbFileExists(filename.c_str())); + EXPECT_TRUE(FileExists(filename.c_str())); EXPECT_TRUE(SbFileAtomicReplace(filename.c_str(), nullptr, 0)); EXPECT_TRUE(CompareFileContentsToString(filename.c_str(), "\0", 0)); } @@ -80,7 +87,7 @@ TEST(SbFileAtomicReplaceTest, FailsWithNoDataButLength) { ScopedRandomFile random_file(ScopedRandomFile::kCreate); const std::string& filename = random_file.filename(); - EXPECT_TRUE(SbFileExists(filename.c_str())); + EXPECT_TRUE(FileExists(filename.c_str())); EXPECT_FALSE(SbFileAtomicReplace(filename.c_str(), nullptr, 1)); } @@ -88,7 +95,7 @@ TEST(SbFileAtomicReplaceTest, FailsWithInvalidLength) { ScopedRandomFile random_file(ScopedRandomFile::kCreate); const std::string& filename = random_file.filename(); - EXPECT_TRUE(SbFileExists(filename.c_str())); + EXPECT_TRUE(FileExists(filename.c_str())); EXPECT_FALSE(SbFileAtomicReplace(filename.c_str(), kTestContents, -1)); } diff --git a/starboard/nplb/file_delete_recursive_test.cc b/starboard/nplb/file_delete_recursive_test.cc index 7c31fad014a0..95611d25abaa 100644 --- a/starboard/nplb/file_delete_recursive_test.cc +++ b/starboard/nplb/file_delete_recursive_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include "starboard/common/file.h" @@ -43,6 +45,11 @@ const char* kFiles[kFileCount] = { "test2/file3", }; +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(SbFileDeleteRecursiveTest, SunnyDayDeleteExistingPath) { std::string path; const std::string& tmp = GetTempDir(); @@ -51,7 +58,7 @@ TEST(SbFileDeleteRecursiveTest, SunnyDayDeleteExistingPath) { for (size_t i = 0; i < kDirectoryCount; ++i) { path = tmp + kSbFileSepString + kRoot + kSbFileSepString + kDirectories[i]; - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); EXPECT_TRUE(SbDirectoryCreate(path.c_str())); EXPECT_TRUE(SbDirectoryCanOpen(path.c_str())); } @@ -63,39 +70,39 @@ TEST(SbFileDeleteRecursiveTest, SunnyDayDeleteExistingPath) { for (size_t i = 0; i < kFileCount; ++i) { path = tmp + kSbFileSepString + kRoot + kSbFileSepString + kFiles[i]; - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); file = SbFileOpen(path.c_str(), kSbFileCreateAlways | kSbFileWrite, NULL, &err); EXPECT_EQ(kSbFileOk, err); EXPECT_TRUE(SbFileClose(file)); - EXPECT_TRUE(SbFileExists(path.c_str())); + EXPECT_TRUE(FileExists(path.c_str())); } path = tmp + kSbFileSepString + kRoot; EXPECT_TRUE(SbFileDeleteRecursive(path.c_str(), false)); - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); } TEST(SbFileDeleteRecursiveTest, SunnyDayDeletePreserveRoot) { const std::string root = GetTempDir() + kSbFileSepString + kRoot; - EXPECT_FALSE(SbFileExists(root.c_str())); + EXPECT_FALSE(FileExists(root.c_str())); EXPECT_TRUE(SbDirectoryCreate(root.c_str())); EXPECT_TRUE(SbDirectoryCanOpen(root.c_str())); EXPECT_TRUE(SbFileDeleteRecursive(root.c_str(), true)); - EXPECT_TRUE(SbFileExists(root.c_str())); + EXPECT_TRUE(FileExists(root.c_str())); EXPECT_TRUE(SbFileDeleteRecursive(root.c_str(), false)); - EXPECT_FALSE(SbFileExists(root.c_str())); + EXPECT_FALSE(FileExists(root.c_str())); } TEST(SbFileDeleteRecursiveTest, RainyDayDeleteFileIgnoresPreserveRoot) { const std::string& path = GetTempDir() + kSbFileSepString + "file1"; - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); SbFileError err = kSbFileOk; SbFile file = kSbFileInvalid; @@ -105,15 +112,15 @@ TEST(SbFileDeleteRecursiveTest, RainyDayDeleteFileIgnoresPreserveRoot) { EXPECT_EQ(kSbFileOk, err); EXPECT_TRUE(SbFileClose(file)); - EXPECT_TRUE(SbFileExists(path.c_str())); + EXPECT_TRUE(FileExists(path.c_str())); EXPECT_TRUE(SbFileDeleteRecursive(path.c_str(), true)); - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); } TEST(SbFileDeleteRecursiveTest, RainyDayNonExistentPathErrors) { ScopedRandomFile file(ScopedRandomFile::kDontCreate); - EXPECT_FALSE(SbFileExists(file.filename().c_str())); + EXPECT_FALSE(FileExists(file.filename().c_str())); EXPECT_FALSE(SbFileDeleteRecursive(file.filename().c_str(), false)); } diff --git a/starboard/nplb/file_delete_test.cc b/starboard/nplb/file_delete_test.cc index cea7b611b7f4..79add830b142 100644 --- a/starboard/nplb/file_delete_test.cc +++ b/starboard/nplb/file_delete_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include "starboard/file.h" @@ -22,10 +24,15 @@ namespace starboard { namespace nplb { namespace { +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(SbFileDeleteTest, SunnyDayDeleteExistingFile) { ScopedRandomFile file; - EXPECT_TRUE(SbFileExists(file.filename().c_str())); + EXPECT_TRUE(FileExists(file.filename().c_str())); EXPECT_TRUE(SbFileDelete(file.filename().c_str())); } @@ -34,7 +41,7 @@ TEST(SbFileDeleteTest, SunnyDayDeleteExistingDirectory) { const std::string& path = file.filename(); - EXPECT_FALSE(SbFileExists(path.c_str())); + EXPECT_FALSE(FileExists(path.c_str())); EXPECT_TRUE(SbDirectoryCreate(path.c_str())); EXPECT_TRUE(SbDirectoryCanOpen(path.c_str())); EXPECT_TRUE(SbFileDelete(path.c_str())); @@ -43,7 +50,7 @@ TEST(SbFileDeleteTest, SunnyDayDeleteExistingDirectory) { TEST(SbFileDeleteTest, RainyDayNonExistentFileErrors) { ScopedRandomFile file(ScopedRandomFile::kDontCreate); - EXPECT_FALSE(SbFileExists(file.filename().c_str())); + EXPECT_FALSE(FileExists(file.filename().c_str())); EXPECT_TRUE(SbFileDelete(file.filename().c_str())); } diff --git a/starboard/nplb/file_open_test.cc b/starboard/nplb/file_open_test.cc index c9b795bec92c..ae19dec24c1e 100644 --- a/starboard/nplb/file_open_test.cc +++ b/starboard/nplb/file_open_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include @@ -40,8 +42,10 @@ void BasicTest(bool existing, << ", original_line=" << original_line if (!existing) { - EXPECT_FALSE(SbFileExists(filename.c_str())) << SB_FILE_OPEN_TEST_CONTEXT; - if (SbFileExists(filename.c_str())) { + struct stat info; + EXPECT_FALSE(stat(filename.c_str(), &info) == 0) + << SB_FILE_OPEN_TEST_CONTEXT; + if (stat(filename.c_str(), &info) == 0) { return; } } diff --git a/starboard/nplb/log_raw_dump_stack_test.cc b/starboard/nplb/log_raw_dump_stack_test.cc index b9a887de23d0..779f4cd4963b 100644 --- a/starboard/nplb/log_raw_dump_stack_test.cc +++ b/starboard/nplb/log_raw_dump_stack_test.cc @@ -18,23 +18,25 @@ #include "starboard/common/log.h" #include "testing/gtest/include/gtest/gtest.h" +#include "starboard/shared/testing/no_inline.h" + namespace starboard { namespace nplb { namespace { -SB_C_NOINLINE void DumpMoreStack() { +SB_TEST_FORCE_NO_INLINE void DumpMoreStack() { SbLogRawDumpStack(0); } -SB_C_NOINLINE void DumpEvenMoreStack() { +SB_TEST_FORCE_NO_INLINE void DumpEvenMoreStack() { DumpMoreStack(); } -SB_C_NOINLINE void DumpStackBigTime() { +SB_TEST_FORCE_NO_INLINE void DumpStackBigTime() { DumpEvenMoreStack(); } -SB_C_NOINLINE void IShouldBeSkipped() { +SB_TEST_FORCE_NO_INLINE void IShouldBeSkipped() { SbLogRawDumpStack(1); } diff --git a/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc b/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc index 2b07856c02bd..553c892ca81b 100644 --- a/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc +++ b/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include @@ -44,7 +46,8 @@ TEST_F(CrashpadConfigTest, VerifyUploadCert) { kSbFileSepString + "cobalt" + kSbFileSepString + "content" + kSbFileSepString + "ssl" + kSbFileSepString + "certs"); - ASSERT_TRUE(SbFileExists(cert_location.c_str())); + struct stat info; + ASSERT_TRUE(stat(cert_location.c_str(), &info) == 0); } TEST_F(CrashpadConfigTest, VerifyCrashHandlerExtension) { diff --git a/starboard/nplb/nplb_evergreen_compat_tests/fonts_test.cc b/starboard/nplb/nplb_evergreen_compat_tests/fonts_test.cc index 091a496dc76c..1da56bdd77a4 100644 --- a/starboard/nplb/nplb_evergreen_compat_tests/fonts_test.cc +++ b/starboard/nplb/nplb_evergreen_compat_tests/fonts_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include @@ -36,18 +38,24 @@ TEST(FontsTest, VerifySystemFontsDirectory) { std::vector system_fonts_dir(kSbFileMaxPath); ASSERT_TRUE(SbSystemGetPath(kSbSystemPathFontDirectory, system_fonts_dir.data(), kSbFileMaxPath)); - ASSERT_TRUE(SbFileExists(system_fonts_dir.data())); + + struct stat info; + ASSERT_TRUE(stat(system_fonts_dir.data(), &info) == 0); } TEST(FontsTest, VerifySystemFontsConfigDirectory) { std::vector system_fonts_conf_dir(kSbFileMaxPath); ASSERT_TRUE(SbSystemGetPath(kSbSystemPathFontConfigurationDirectory, system_fonts_conf_dir.data(), kSbFileMaxPath)); - ASSERT_TRUE(SbFileExists(system_fonts_conf_dir.data())); + struct stat info; + ASSERT_TRUE(stat(system_fonts_conf_dir.data(), &info) == 0); + std::string fonts_descriptor_file = system_fonts_conf_dir.data(); fonts_descriptor_file += kSbFileSepString; fonts_descriptor_file += kFileName; - ASSERT_TRUE(SbFileExists(fonts_descriptor_file.c_str())); + + struct stat file_info; + ASSERT_TRUE(stat(fonts_descriptor_file.c_str(), &file_info) == 0); } } // namespace diff --git a/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc b/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc index 2445fd4adf4a..ce0179dde0cf 100644 --- a/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc +++ b/starboard/nplb/nplb_evergreen_compat_tests/storage_test.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include @@ -82,7 +84,8 @@ TEST_F(StorageTest, VerifyStorageDirectory) { } ASSERT_TRUE(SbFileDelete(file_path.data())); - ASSERT_FALSE(SbFileExists(file_path.data())); + struct stat info; + ASSERT_FALSE(stat(file_path.data(), &info) == 0); } } // namespace diff --git a/starboard/nplb/posix_compliance/posix_directory_can_open_test.cc b/starboard/nplb/posix_compliance/posix_directory_can_open_test.cc new file mode 100644 index 000000000000..399ea3baf249 --- /dev/null +++ b/starboard/nplb/posix_compliance/posix_directory_can_open_test.cc @@ -0,0 +1,68 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include + +#include "starboard/configuration_constants.h" +#include "starboard/directory.h" +#include "starboard/nplb/file_helpers.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace starboard { +namespace nplb { +namespace { + +TEST(PosixDirectoryCanOpenTest, SunnyDay) { + std::string path = starboard::nplb::GetTempDir(); + struct stat file_info; + EXPECT_FALSE(path.empty()); + EXPECT_TRUE(stat(path.c_str(), &file_info) == 0); + + EXPECT_TRUE(S_ISDIR(file_info.st_mode)); +} + +TEST(PosixDirectoryCanOpenTest, SunnyDayStaticContent) { + for (auto dir_path : GetFileTestsDirectoryPaths()) { + struct stat file_info; + stat(dir_path.c_str(), &file_info); + EXPECT_TRUE(S_ISDIR(file_info.st_mode)) << "Can't open: " << dir_path; + } +} + +TEST(PosixDirectoryCanOpenTest, FailureMissingStaticContent) { + std::string directory_path = GetFileTestsDataDir(); + std::string missing_dir = directory_path + kSbFileSepChar + "missing_dir"; + struct stat file_info; + stat(missing_dir.c_str(), &file_info); + EXPECT_FALSE(S_ISDIR(file_info.st_mode)); +} + +TEST(PosixDirectoryCanOpenTest, FailureEmpty) { + struct stat file_info; + EXPECT_FALSE(stat("", &file_info) == 0); +} + +TEST(PosixDirectoryCanOpenTest, FailureRegularFile) { + starboard::nplb::ScopedRandomFile file; + struct stat file_info; + + EXPECT_TRUE(stat(file.filename().c_str(), &file_info) == 0); + EXPECT_FALSE(S_ISDIR(file_info.st_mode)); +} + +} // namespace +} // namespace nplb +} // namespace starboard diff --git a/starboard/nplb/posix_compliance/posix_file_get_path_info_test.cc b/starboard/nplb/posix_compliance/posix_file_get_path_info_test.cc new file mode 100644 index 000000000000..2a5a857cc5b6 --- /dev/null +++ b/starboard/nplb/posix_compliance/posix_file_get_path_info_test.cc @@ -0,0 +1,134 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// GetInfo is mostly tested in the course of other tests. + +#include + +#include + +#include "starboard/common/time.h" +#include "starboard/configuration_constants.h" +#include "starboard/file.h" +#include "starboard/nplb/file_helpers.h" +#include "starboard/system.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace starboard { +namespace nplb { +namespace { + +static inline int64_t TimeTToWindowsUsecTest(time_t time) { + int64_t posix_usec = static_cast(time) * 1000000; + return PosixTimeToWindowsTime(posix_usec); +} + +TEST(PosixFileGetPathInfoTest, InvalidFileErrors) { + struct stat file_info; + + EXPECT_FALSE(stat("", &file_info) == 0); + + EXPECT_TRUE(stat(".", &file_info) == 0); +} + +TEST(PosixFileGetPathInfoTest, WorksOnARegularFile) { + // This test is potentially flaky because it's comparing times. So, building + // in extra sensitivity to make flakiness more apparent. + const int kTrials = 100; + for (int i = 0; i < kTrials; ++i) { + // We can't assume filesystem timestamp precision, so go back a minute + // for a better chance to contain the imprecision and rounding errors. + const int64_t kOneSecondInMicroseconds = 1'000'000; + int64_t time = PosixTimeToWindowsTime(CurrentPosixTime()); +#if !SB_HAS_QUIRK(FILESYSTEM_ZERO_FILEINFO_TIME) +#if SB_HAS_QUIRK(FILESYSTEM_COARSE_ACCESS_TIME) + // On platforms with coarse access time, we assume 1 day precision and go + // back 2 days to avoid rounding issues. + const int64_t kOneDayInMicroseconds = 1'000'000LL * 60LL * 60LL * 24LL; +#endif // FILESYSTEM_COARSE_ACCESS_TIME +#endif // FILESYSTEM_ZERO_FILEINFO_TIME + + const int kFileSize = 12; + ScopedRandomFile random_file(kFileSize); + const std::string& filename = random_file.filename(); + + { + struct stat file_info; + EXPECT_TRUE(stat(filename.c_str(), &file_info) == 0); + EXPECT_EQ(kFileSize, file_info.st_size); + EXPECT_FALSE(S_ISDIR(file_info.st_mode)); + EXPECT_FALSE(S_ISLNK(file_info.st_mode)); +#if SB_HAS_QUIRK(FILESYSTEM_ZERO_FILEINFO_TIME) + EXPECT_LE(0, TimeTToWindowsUsecTest(file_info.at_ctime)); + EXPECT_LE(0, TimeTToWindowsUsecTest(file_info.mt_ctime)); + EXPECT_LE(0, TimeTToWindowsUsecTest(file_info.st_ctime)); +#else + EXPECT_NEAR(time, TimeTToWindowsUsecTest(file_info.st_mtime), + kOneSecondInMicroseconds); +#if SB_HAS_QUIRK(FILESYSTEM_COARSE_ACCESS_TIME) + EXPECT_NEAR(time, TimeTToWindowsUsecTest(file_info.at_ctime), + 2 * kOneDayInMicroseconds); +#else + EXPECT_NEAR(time, TimeTToWindowsUsecTest(file_info.st_atime), + kOneSecondInMicroseconds); +#endif // FILESYSTEM_COARSE_ACCESS_TIME + EXPECT_NEAR(time, TimeTToWindowsUsecTest(file_info.st_ctime), + kOneSecondInMicroseconds); +#endif // FILESYSTEM_ZERO_FILEINFO_TIME + } + } +} + +TEST(PosixFileGetPathInfoTest, WorksOnADirectory) { + std::vector path(kSbFileMaxPath); + bool result = + SbSystemGetPath(kSbSystemPathTempDirectory, path.data(), kSbFileMaxPath); + EXPECT_TRUE(result); + + { + struct stat file_info; + bool result = stat(path.data(), &file_info) == 0; + EXPECT_LE(0, file_info.st_size); + EXPECT_TRUE(S_ISDIR(file_info.st_mode)); + EXPECT_FALSE(S_ISLNK(file_info.st_mode)); + EXPECT_LE(0, file_info.st_mtime); + EXPECT_LE(0, file_info.st_atime); + EXPECT_LE(0, file_info.st_ctime); + } +} + +TEST(PosixFileGetPathInfoTest, WorksOnStaticContentFiles) { + for (auto filename : GetFileTestsFilePaths()) { + struct stat info; + EXPECT_TRUE(stat(filename.c_str(), &info) == 0); + size_t content_length = GetTestFileExpectedContent(filename).length(); + EXPECT_EQ(content_length, info.st_size); + EXPECT_FALSE(S_ISDIR(info.st_mode)); + EXPECT_FALSE(S_ISLNK(info.st_mode)); + } +} + +TEST(PosixFileGetPathInfoTest, WorksOnStaticContentDirectories) { + for (auto path : GetFileTestsDirectoryPaths()) { + struct stat info; + EXPECT_TRUE(stat(path.data(), &info) == 0); + EXPECT_LE(0, info.st_size); + EXPECT_TRUE(S_ISDIR(info.st_mode)); + EXPECT_FALSE(S_ISLNK(info.st_mode)); + } +} + +} // namespace +} // namespace nplb +} // namespace starboard diff --git a/starboard/nplb/posix_compliance/posix_file_open_test.cc b/starboard/nplb/posix_compliance/posix_file_open_test.cc index 52ba9078d2f5..6656145e0537 100644 --- a/starboard/nplb/posix_compliance/posix_file_open_test.cc +++ b/starboard/nplb/posix_compliance/posix_file_open_test.cc @@ -43,8 +43,10 @@ void BasicTest(bool existing, << ", original_line=" << original_line if (!existing) { - EXPECT_FALSE(SbFileExists(filename.c_str())) << SB_FILE_OPEN_TEST_CONTEXT; - if (SbFileExists(filename.c_str())) { + struct stat file_info; + bool file_exists = stat(filename.c_str(), &file_info) == 0; + EXPECT_FALSE(file_exists) << SB_FILE_OPEN_TEST_CONTEXT; + if (file_exists) { return; } } diff --git a/starboard/nplb/system_get_path_test.cc b/starboard/nplb/system_get_path_test.cc index 3f2b2cdaa8d9..146e7def8b35 100644 --- a/starboard/nplb/system_get_path_test.cc +++ b/starboard/nplb/system_get_path_test.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -66,6 +67,11 @@ void UnmodifiedOnFailureTest(SbSystemPathId id, int line) { } } +bool FileExists(const char* path) { + struct stat info; + return stat(path, &info) == 0; +} + TEST(SbSystemGetPathTest, ReturnsRequiredPaths) { BasicTest(kSbSystemPathContentDirectory, true, true, __LINE__); BasicTest(kSbSystemPathCacheDirectory, true, true, __LINE__); @@ -126,11 +132,11 @@ TEST(SbSystemGetPathTest, CanCreateAndRemoveDirectoryInCache) { kSbFileSepString + ScopedRandomFile::MakeRandomFilename(); EXPECT_GT(starboard::strlcat(path.data(), sub_path.c_str(), kPathSize), 0); EXPECT_TRUE(SbFileDelete(path.data())); - EXPECT_FALSE(SbFileExists(path.data())); + EXPECT_FALSE(FileExists(path.data())); // Create the directory and confirm it exists and can be opened. EXPECT_TRUE(SbDirectoryCreate(path.data())); - EXPECT_TRUE(SbFileExists(path.data())); + EXPECT_TRUE(FileExists(path.data())); EXPECT_TRUE(SbDirectoryCanOpen(path.data())); SbDirectory directory = SbDirectoryOpen(path.data(), NULL); EXPECT_TRUE(SbDirectoryIsValid(directory)); @@ -138,7 +144,7 @@ TEST(SbSystemGetPathTest, CanCreateAndRemoveDirectoryInCache) { // Lastly, close and delete the directory. EXPECT_TRUE(SbDirectoryClose(directory)); EXPECT_TRUE(SbFileDelete(path.data())); - EXPECT_FALSE(SbFileExists(path.data())); + EXPECT_FALSE(FileExists(path.data())); } } @@ -157,7 +163,7 @@ TEST(SbSystemGetPathTest, CanWriteAndReadCache) { kSbFileSepString + ScopedRandomFile::MakeRandomFilename(); EXPECT_GT(starboard::strlcat(path.data(), sub_path.c_str(), kPathSize), 0); EXPECT_TRUE(SbFileDelete(path.data())); - EXPECT_FALSE(SbFileExists(path.data())); + EXPECT_FALSE(FileExists(path.data())); // Write to the file and check that we can read from it. std::string content_to_write = "test content"; @@ -169,7 +175,7 @@ TEST(SbSystemGetPathTest, CanWriteAndReadCache) { static_cast(content_to_write.size())), 0); } - EXPECT_TRUE(SbFileExists(path.data())); + EXPECT_TRUE(FileExists(path.data())); SbFileInfo info; EXPECT_TRUE(SbFileGetPathInfo(path.data(), &info)); const int kFileSize = static_cast(info.size); @@ -185,7 +191,7 @@ TEST(SbSystemGetPathTest, CanWriteAndReadCache) { // Lastly, delete the file. EXPECT_TRUE(SbFileDelete(path.data())); - EXPECT_FALSE(SbFileExists(path.data())); + EXPECT_FALSE(FileExists(path.data())); } } diff --git a/starboard/nplb/system_get_stack_test.cc b/starboard/nplb/system_get_stack_test.cc index 9b0f3db6efc6..7c4009185696 100644 --- a/starboard/nplb/system_get_stack_test.cc +++ b/starboard/nplb/system_get_stack_test.cc @@ -16,11 +16,14 @@ #include "starboard/system.h" #include "testing/gtest/include/gtest/gtest.h" +#include "starboard/shared/testing/no_inline.h" + namespace starboard { namespace nplb { namespace { -SB_C_NOINLINE int GetStackWithAnExtraFrame(void** out_stack, int stack_size) { +SB_TEST_FORCE_NO_INLINE int GetStackWithAnExtraFrame(void** out_stack, + int stack_size) { // These EXPECT_NE and EXPECT_LT should be enough to make function complicated // and avoid inlining with optimizations on some platforms. But we'll have to // keep an eye on it as this may not be enough on some other platforms. @@ -31,7 +34,7 @@ SB_C_NOINLINE int GetStackWithAnExtraFrame(void** out_stack, int stack_size) { return ret; } -SB_C_NOINLINE void WowThatsADeepStack() { +SB_TEST_FORCE_NO_INLINE void WowThatsADeepStack() { void* stack1[10] = {0}; void* stack2[10] = {0}; EXPECT_LT(0, SbSystemGetStack(stack1, SB_ARRAY_SIZE_INT(stack1))); diff --git a/starboard/nplb/undefined_behavior_test.cc b/starboard/nplb/undefined_behavior_test.cc index 6e416d4aa918..921505603054 100644 --- a/starboard/nplb/undefined_behavior_test.cc +++ b/starboard/nplb/undefined_behavior_test.cc @@ -14,13 +14,15 @@ #include "testing/gtest/include/gtest/gtest.h" +#include "starboard/shared/testing/no_inline.h" + namespace starboard { namespace nplb { namespace { class Object { public: - SB_C_NOINLINE bool ThisPointerIsNull() { + SB_TEST_FORCE_NO_INLINE bool ThisPointerIsNull() { auto* pointer = this; // Intentionally not "return !pointer", and with a side effect for one // branch, in order to more closely match the form that this undefined diff --git a/starboard/raspi/shared/configuration_public.h b/starboard/raspi/shared/configuration_public.h index c25e6c8fee27..83630fba63e3 100644 --- a/starboard/raspi/shared/configuration_public.h +++ b/starboard/raspi/shared/configuration_public.h @@ -52,10 +52,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/shared/modular/BUILD.gn b/starboard/shared/modular/BUILD.gn index 9226065c5445..c72810ffd18c 100644 --- a/starboard/shared/modular/BUILD.gn +++ b/starboard/shared/modular/BUILD.gn @@ -20,6 +20,8 @@ source_set("starboard_layer_posix_abi_wrappers") { "starboard_layer_posix_mmap_abi_wrappers.h", "starboard_layer_posix_pthread_abi_wrappers.cc", "starboard_layer_posix_pthread_abi_wrappers.h", + "starboard_layer_posix_stat_abi_wrappers.cc", + "starboard_layer_posix_stat_abi_wrappers.h", "starboard_layer_posix_time_abi_wrappers.cc", "starboard_layer_posix_time_abi_wrappers.h", ] @@ -35,6 +37,7 @@ if (sb_is_modular && !sb_is_evergreen && sources = [ "cobalt_layer_posix_mmap_abi_wrappers.cc", "cobalt_layer_posix_pthread_abi_wrappers.cc", + "cobalt_layer_posix_stat_abi_wrappers.cc", "cobalt_layer_posix_time_abi_wrappers.cc", ] } diff --git a/starboard/shared/modular/cobalt_layer_posix_stat_abi_wrappers.cc b/starboard/shared/modular/cobalt_layer_posix_stat_abi_wrappers.cc new file mode 100644 index 000000000000..c37d48557a97 --- /dev/null +++ b/starboard/shared/modular/cobalt_layer_posix_stat_abi_wrappers.cc @@ -0,0 +1,28 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if SB_API_VERSION >= 16 + +#include + +extern "C" { + +int __abi_wrap_stat(const char* path, struct stat* info); + +int stat(const char* path, struct stat* info) { + return __abi_wrap_stat(path, info); +} +} + +#endif // SB_API_VERSION >= 16 diff --git a/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.cc b/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.cc new file mode 100644 index 000000000000..8878bf425ac9 --- /dev/null +++ b/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.cc @@ -0,0 +1,51 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h" + +int __abi_wrap_stat(const char* path, struct musl_stat* musl_info) { + struct stat stat_info; // The type from platform toolchain. + int retval = stat(path, &stat_info); + + if (retval != 0 || musl_info == NULL) { + return -1; + } + + musl_info->st_size = stat_info.st_size; + musl_info->st_mode = stat_info.st_mode; +#if defined(_MSC_VER) + musl_info->st_atim.tv_sec = stat_info.st_atime; + musl_info->st_atim.tv_nsec = 0; + musl_info->st_mtim.tv_sec = stat_info.st_mtime; + musl_info->st_mtim.tv_nsec = 0; + musl_info->st_ctim.tv_sec = stat_info.st_ctime; + musl_info->st_ctim.tv_nsec = 0; +#elif defined(__APPLE__) + musl_info->st_atim.tv_sec = 0; + musl_info->st_atim.tv_nsec = 0; + musl_info->st_mtim.tv_sec = 0; + musl_info->st_mtim.tv_nsec = 0; + musl_info->st_ctim.tv_sec = 0; + musl_info->st_ctim.tv_nsec = 0; +#else + musl_info->st_atim.tv_sec = stat_info.st_atim.tv_sec; + musl_info->st_atim.tv_nsec = stat_info.st_atim.tv_nsec; + musl_info->st_mtim.tv_sec = stat_info.st_mtim.tv_sec; + musl_info->st_mtim.tv_nsec = stat_info.st_mtim.tv_nsec; + musl_info->st_ctim.tv_sec = stat_info.st_ctim.tv_sec; + musl_info->st_ctim.tv_nsec = stat_info.st_ctim.tv_nsec; +#endif + + return retval; +} diff --git a/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h b/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h new file mode 100644 index 000000000000..976e1593a9e6 --- /dev/null +++ b/starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h @@ -0,0 +1,84 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Module Overview: POSIX stat wrappers +// +// These wrappers are used in modular builds (including Evergreen). They +// are needed to handle dealing with differences in platform-specific +// toolchain types and musl-based types. In particular, the `struct stat` +// type may contain differently sized member fields and when the caller is +// Cobalt code compiled with musl it will provide argument data that needs +// to be adjusted when passed to platform-specific system libraries. + +#ifndef STARBOARD_SHARED_MODULAR_STARBOARD_LAYER_POSIX_STAT_ABI_WRAPPERS_H_ +#define STARBOARD_SHARED_MODULAR_STARBOARD_LAYER_POSIX_STAT_ABI_WRAPPERS_H_ + +#include // This should be the headers from the platform toolchain + +#include "starboard/configuration.h" +#include "starboard/export.h" +#include "starboard/shared/modular/starboard_layer_posix_time_abi_wrappers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct musl_stat { +#if SB_IS(ARCH_ARM64) || SB_IS(ARCH_X64) + int64_t /*dev_t*/ st_dev; + int64_t /*ino_t*/ st_ino; + int64_t /*nlink_t*/ st_nlink; + + unsigned /*mode_t*/ st_mode; + unsigned /*uid_t*/ st_uid; + unsigned /*gid_t*/ st_gid; + unsigned /*unsigned int*/ __pad0; + int64_t /*dev_t*/ st_rdev; + int64_t /*off_t*/ st_size; + int64_t /*blksize_t*/ st_blksize; + int64_t /*blkcnt_t*/ st_blocks; + + struct musl_timespec /*struct timespec*/ st_atim; + struct musl_timespec /*struct timespec*/ st_mtim; + struct musl_timespec /*struct timespec*/ st_ctim; + int64_t unused[3]; +#else + uint64_t /*dev_t*/ st_dev; + uint32_t /*int*/ _st_dev_padding; + int32_t /*long*/ _st_ino_truncated; + + uint32_t /*mode_t*/ st_mode; + uint32_t /*nlink_t*/ st_nlink; + uint32_t /*uid_t*/ st_uid; + uint32_t /*gid_t*/ st_gid; + uint64_t /*dev_t*/ st_rdev; + uint32_t /*int*/ __st_rdev_padding; + int64_t /*off_t*/ st_size; + int32_t /*blksize_t*/ st_blksize; + int64_t /*blkcnt_t*/ st_blocks; + int32_t _unused[6]; + uint64_t /*ino_t*/ st_ino; + struct musl_timespec /*struct timespec*/ st_atim; + struct musl_timespec /*struct timespec*/ st_mtim; + struct musl_timespec /*struct timespec*/ st_ctim; +#endif +}; + +SB_EXPORT int __abi_wrap_stat(const char* path, struct musl_stat* info); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // STARBOARD_SHARED_MODULAR_STARBOARD_LAYER_POSIX_STAT_ABI_WRAPPERS_H_ diff --git a/starboard/shared/posix/file_atomic_replace.cc b/starboard/shared/posix/file_atomic_replace.cc index 0b68518a72b3..ddec1db37c28 100644 --- a/starboard/shared/posix/file_atomic_replace.cc +++ b/starboard/shared/posix/file_atomic_replace.cc @@ -14,6 +14,8 @@ #include "starboard/file.h" +#include + #include #include @@ -35,7 +37,8 @@ bool SbFileAtomicReplace(const char* path, return false; } - const bool file_exists = SbFileExists(path); + struct stat file_info; + const bool file_exists = stat(path, &file_info) == 0; std::vector temp_path(kSbFileMaxPath + 1, 0); starboard::strlcpy(temp_path.data(), path, kSbFileMaxPath); diff --git a/starboard/shared/posix/file_exists.cc b/starboard/shared/posix/file_exists.cc index 6e54c67f9340..b418a4692d9b 100644 --- a/starboard/shared/posix/file_exists.cc +++ b/starboard/shared/posix/file_exists.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#if SB_API_VERSION < 16 + #include "starboard/shared/posix/file_internal.h" #include "starboard/shared/posix/impl/file_exists.h" @@ -19,3 +21,4 @@ bool SbFileExists(const char* path) { return ::starboard::shared::posix::impl::FileExists(path); } +#endif diff --git a/starboard/shared/stub/file_exists.cc b/starboard/shared/stub/file_exists.cc index 120713774801..f446ca18ceee 100644 --- a/starboard/shared/stub/file_exists.cc +++ b/starboard/shared/stub/file_exists.cc @@ -12,8 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#if SB_API_VERSION < 16 + #include "starboard/file.h" bool SbFileExists(const char* path) { return false; } +#endif diff --git a/starboard/shared/testing/no_inline.h b/starboard/shared/testing/no_inline.h new file mode 100644 index 000000000000..33ebc1f6a1fa --- /dev/null +++ b/starboard/shared/testing/no_inline.h @@ -0,0 +1,25 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STARBOARD_SHARED_TESTING_NO_INLINE_H_ +#define STARBOARD_SHARED_TESTING_NO_INLINE_H_ +#if defined(__GNUC__) +#define SB_TEST_FORCE_NO_INLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define SB_TEST_FORCE_NO_INLINE __declspec(noinline) +#else +#error "Your compiler is not supported" +#endif + +#endif // STARBOARD_SHARED_TESTING_NO_INLINE_H_ diff --git a/starboard/shared/win32/file_delete.cc b/starboard/shared/win32/file_delete.cc index 268263afed81..2d5aa0cba3bd 100644 --- a/starboard/shared/win32/file_delete.cc +++ b/starboard/shared/win32/file_delete.cc @@ -26,8 +26,8 @@ bool SbFileDelete(const char* path) { if ((path == nullptr) || *path == '\0') { return false; } - - if (!SbFileExists(path)) { + struct stat info; + if (stat(path, &info) != 0) { return true; } diff --git a/starboard/shared/win32/file_exists.cc b/starboard/shared/win32/file_exists.cc index 677ddb55085d..3072769ecbea 100644 --- a/starboard/shared/win32/file_exists.cc +++ b/starboard/shared/win32/file_exists.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#if SB_API_VERSION < 16 + #include "starboard/file.h" #include @@ -50,3 +52,4 @@ bool SbFileExists(const char* path) { return PathEndsWith(path_wstring, find_data.cFileName); } +#endif diff --git a/starboard/shared/win32/file_internal.cc b/starboard/shared/win32/file_internal.cc index b4835b661f68..de07d48bd657 100644 --- a/starboard/shared/win32/file_internal.cc +++ b/starboard/shared/win32/file_internal.cc @@ -14,6 +14,8 @@ #include "starboard/shared/win32/file_internal.h" +#include + #include #include "starboard/common/log.h" @@ -160,13 +162,14 @@ HANDLE OpenFileOrDirectory(const char* path, create_ex_params.dwSecurityQosFlags = SECURITY_ANONYMOUS; create_ex_params.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); - const bool file_exists_prior_to_open = SbFileExists(path); + struct stat info; + const bool file_exists_prior_to_open = stat(path, &info) == 0; HANDLE file_handle = CreateFile2(path_wstring.c_str(), desired_access, share_mode, creation_disposition, &create_ex_params); - const bool file_exists_after_open = SbFileExists(path); + const bool file_exists_after_open = stat(path, &info) == 0; if (out_created && starboard::shared::win32::IsValidHandle(file_handle)) { if (flags & kSbFileCreateAlways) { diff --git a/starboard/shared/win32/posix_emu/include/sys/stat.h b/starboard/shared/win32/posix_emu/include/sys/stat.h new file mode 100644 index 000000000000..6c3d23bed1f6 --- /dev/null +++ b/starboard/shared/win32/posix_emu/include/sys/stat.h @@ -0,0 +1,30 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_STAT_H_ +#define STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_STAT_H_ + +#include <../ucrt/sys/stat.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define S_ISLNK(mode) 0 // Windows doesn't support symbolic links +#define S_ISDIR(mode) (((mode) & _S_IFMT) == (_S_IFDIR)) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_STAT_H_ diff --git a/starboard/stub/configuration_public.h b/starboard/stub/configuration_public.h index 8c6204941691..f57b408bccb9 100644 --- a/starboard/stub/configuration_public.h +++ b/starboard/stub/configuration_public.h @@ -57,10 +57,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __attribute__((noinline)) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __attribute__((visibility("default"))) diff --git a/starboard/tools/api_leak_detector/api_leak_detector.py b/starboard/tools/api_leak_detector/api_leak_detector.py index e7056b853005..b577e69baf59 100755 --- a/starboard/tools/api_leak_detector/api_leak_detector.py +++ b/starboard/tools/api_leak_detector/api_leak_detector.py @@ -118,6 +118,7 @@ 'munmap', 'mprotect', 'msync', + 'stat', ] diff --git a/starboard/tools/api_leak_detector/stub/debug/docker_debian10_manifest b/starboard/tools/api_leak_detector/stub/debug/docker_debian10_manifest index 44189ee7f7db..865bded0d2da 100644 --- a/starboard/tools/api_leak_detector/stub/debug/docker_debian10_manifest +++ b/starboard/tools/api_leak_detector/stub/debug/docker_debian10_manifest @@ -53,6 +53,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bind_textdomain_codeset diff --git a/starboard/tools/api_leak_detector/stub/debug/gn_built_docker_debian11_manifest b/starboard/tools/api_leak_detector/stub/debug/gn_built_docker_debian11_manifest index b73a439f13b1..365ffbcf6c8b 100644 --- a/starboard/tools/api_leak_detector/stub/debug/gn_built_docker_debian11_manifest +++ b/starboard/tools/api_leak_detector/stub/debug/gn_built_docker_debian11_manifest @@ -50,6 +50,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bind_textdomain_codeset diff --git a/starboard/tools/api_leak_detector/stub/debug/manifest b/starboard/tools/api_leak_detector/stub/debug/manifest index 786509368dac..620628f9badd 100644 --- a/starboard/tools/api_leak_detector/stub/debug/manifest +++ b/starboard/tools/api_leak_detector/stub/debug/manifest @@ -49,6 +49,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bind_textdomain_codeset diff --git a/starboard/tools/api_leak_detector/stub/devel/docker_debian10_manifest b/starboard/tools/api_leak_detector/stub/devel/docker_debian10_manifest index f22125a1ce90..fe1babed90e0 100644 --- a/starboard/tools/api_leak_detector/stub/devel/docker_debian10_manifest +++ b/starboard/tools/api_leak_detector/stub/devel/docker_debian10_manifest @@ -52,6 +52,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/devel/gn_built_docker_debian11_manifest b/starboard/tools/api_leak_detector/stub/devel/gn_built_docker_debian11_manifest index fad67313c88b..9a73dd769d03 100644 --- a/starboard/tools/api_leak_detector/stub/devel/gn_built_docker_debian11_manifest +++ b/starboard/tools/api_leak_detector/stub/devel/gn_built_docker_debian11_manifest @@ -51,6 +51,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/devel/manifest b/starboard/tools/api_leak_detector/stub/devel/manifest index 4a4642837a47..3587a6bce58c 100644 --- a/starboard/tools/api_leak_detector/stub/devel/manifest +++ b/starboard/tools/api_leak_detector/stub/devel/manifest @@ -50,6 +50,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/gold/docker_debian10_manifest b/starboard/tools/api_leak_detector/stub/gold/docker_debian10_manifest index 106ae25120c7..5b881d393812 100644 --- a/starboard/tools/api_leak_detector/stub/gold/docker_debian10_manifest +++ b/starboard/tools/api_leak_detector/stub/gold/docker_debian10_manifest @@ -50,6 +50,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/gold/gn_built_docker_debian11_manifest b/starboard/tools/api_leak_detector/stub/gold/gn_built_docker_debian11_manifest index 6705419ef829..3382f3b0a69c 100644 --- a/starboard/tools/api_leak_detector/stub/gold/gn_built_docker_debian11_manifest +++ b/starboard/tools/api_leak_detector/stub/gold/gn_built_docker_debian11_manifest @@ -49,6 +49,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/gold/manifest b/starboard/tools/api_leak_detector/stub/gold/manifest index eeb7b3bb0b4d..56785c1a106b 100644 --- a/starboard/tools/api_leak_detector/stub/gold/manifest +++ b/starboard/tools/api_leak_detector/stub/gold/manifest @@ -48,6 +48,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/qa/docker_debian10_manifest b/starboard/tools/api_leak_detector/stub/qa/docker_debian10_manifest index 55278b49d812..c92007baf43b 100644 --- a/starboard/tools/api_leak_detector/stub/qa/docker_debian10_manifest +++ b/starboard/tools/api_leak_detector/stub/qa/docker_debian10_manifest @@ -51,6 +51,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/qa/gn_built_docker_debian11_manifest b/starboard/tools/api_leak_detector/stub/qa/gn_built_docker_debian11_manifest index 79e2925abb69..3d007b120fd9 100644 --- a/starboard/tools/api_leak_detector/stub/qa/gn_built_docker_debian11_manifest +++ b/starboard/tools/api_leak_detector/stub/qa/gn_built_docker_debian11_manifest @@ -50,6 +50,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/tools/api_leak_detector/stub/qa/manifest b/starboard/tools/api_leak_detector/stub/qa/manifest index 9141362f676b..91d24db62a54 100644 --- a/starboard/tools/api_leak_detector/stub/qa/manifest +++ b/starboard/tools/api_leak_detector/stub/qa/manifest @@ -49,6 +49,7 @@ __wcscoll_l __wcsftime_l __wcsxfrm_l __wctype_l +__xstat _setjmp abort bcmp diff --git a/starboard/win/shared/configuration_public.h b/starboard/win/shared/configuration_public.h index e55dde3687e5..906bcac2dc5e 100644 --- a/starboard/win/shared/configuration_public.h +++ b/starboard/win/shared/configuration_public.h @@ -59,10 +59,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __declspec(noinline) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __declspec(dllexport) diff --git a/starboard/xb1/shared/configuration_public.h b/starboard/xb1/shared/configuration_public.h index bf84dfaffdce..63741c84b89e 100644 --- a/starboard/xb1/shared/configuration_public.h +++ b/starboard/xb1/shared/configuration_public.h @@ -18,8 +18,6 @@ #ifndef STARBOARD_XB1_SHARED_CONFIGURATION_PUBLIC_H_ #define STARBOARD_XB1_SHARED_CONFIGURATION_PUBLIC_H_ -// --- Architecture Configuration -------------------------------------------- - // --- System Header Configuration ------------------------------------------- // Any system headers listed here that are not provided by the platform will be @@ -61,10 +59,6 @@ // inlined. #define SB_C_INLINE inline -// The platform's annotation for marking a C function as forcibly not -// inlined. -#define SB_C_NOINLINE __declspec(noinline) - // The platform's annotation for marking a symbol as exported outside of the // current shared library. #define SB_EXPORT_PLATFORM __declspec(dllexport) diff --git a/third_party/crashpad/wrapper/wrapper.cc b/third_party/crashpad/wrapper/wrapper.cc index 94ed7f5f8643..b5fd2436755a 100644 --- a/third_party/crashpad/wrapper/wrapper.cc +++ b/third_party/crashpad/wrapper/wrapper.cc @@ -14,6 +14,8 @@ #include "third_party/crashpad/wrapper/wrapper.h" +#include + #include #include @@ -206,7 +208,8 @@ void InstallCrashpadHandler(const std::string& ca_certificates_path) { ::crashpad::CrashpadClient* client = GetCrashpadClient(); const base::FilePath handler_path = GetPathToCrashpadHandlerBinary(); - if (!SbFileExists(handler_path.value().c_str())) { + struct stat file_info; + if (stat(handler_path.value().c_str(), &file_info) != 0) { LOG(ERROR) << "crashpad_handler not at expected location of " << handler_path.value(); RecordStatus( diff --git a/third_party/musl/BUILD.gn b/third_party/musl/BUILD.gn index e855279442d3..10d932404b9e 100644 --- a/third_party/musl/BUILD.gn +++ b/third_party/musl/BUILD.gn @@ -402,6 +402,7 @@ static_library("c_internal") { "src/starboard/time/clock_gettime.c", "src/starboard/time/gmtime_r.c", "src/starboard/time/time.c", + "src/starboard/sys/stat.c", "src/stdio/__toread.c", "src/stdio/__uflow.c", "src/stdio/fprintf.c", diff --git a/third_party/musl/include/sys/stat.h b/third_party/musl/include/sys/stat.h index e6d0049c3d90..9f5abb81c935 100644 --- a/third_party/musl/include/sys/stat.h +++ b/third_party/musl/include/sys/stat.h @@ -111,7 +111,9 @@ int lchmod(const char *, mode_t); #endif #if _REDIR_TIME64 +#if !defined(STARBOARD) __REDIR(stat, __stat_time64); +#endif // !defined(STARBOARD) __REDIR(fstat, __fstat_time64); __REDIR(lstat, __lstat_time64); __REDIR(fstatat, __fstatat_time64); diff --git a/third_party/musl/src/starboard/sys/stat.c b/third_party/musl/src/starboard/sys/stat.c new file mode 100644 index 000000000000..6a32915f42ea --- /dev/null +++ b/third_party/musl/src/starboard/sys/stat.c @@ -0,0 +1,49 @@ +#if SB_API_VERSION < 16 + +#include +#include + +#include +#include +#include "starboard/directory.h" + +int mkdir(const char *path, mode_t mode) +{ + if (SbDirectoryCreate(path)){ + return 0; + } + return -1; +} + +// Reverse implementation of TimeTToWindowsUsec and PosixTimeToWindowsTime for backwards compatibility +// TimeTToWindowsUsec converts to microseconds (*1000000) and then calls PosixTimeToWindowsTime +// PosixTimeToWindows time adds number of microseconds since Jan 1, 1601 (UTC) until Jan 1, 1970 (UTC) +static SB_C_FORCE_INLINE time_t WindowsUsecToTimeT(int64_t time) { + int64_t posix_time = time - 11644473600000000ULL; + posix_time = posix_time / 1000000; + return posix_time; +} + +// SbDirectoryCanOpen, SbFileGetPathInfo, SbFileExists, SbFileCanOpen +int stat(const char *path, struct stat *file_info) +{ + SbFileInfo out_info; + if (!SbFileGetPathInfo(path, &out_info)){ + return -1; + } + + file_info -> st_mode = 0; + if (out_info.is_directory){ + file_info->st_mode = S_IFDIR; + } else if (out_info.is_symbolic_link){ + file_info->st_mode = S_IFLNK; + } + + file_info->st_ctime = WindowsUsecToTimeT(out_info.creation_time); + file_info->st_atime = WindowsUsecToTimeT(out_info.last_accessed); + file_info->st_mtime = WindowsUsecToTimeT(out_info.last_modified); + file_info->st_size = out_info.size; + + return 0; +} +#endif // SB_API_VERSION < 16