// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #define _DEFAULT_SOURCE // for mkstemps(). #include "tools/benchmark/benchmark_utils.h" #include #include #include "lib/jxl/base/status.h" // Not supported on Windows due to Linux-specific functions. // Not supported in Android NDK before API 28. #if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && \ (!defined(__ANDROID_API__) || __ANDROID_API__ >= 28) #include #include #include #include #include #include #include #include extern char** environ; // NOLINT namespace jpegxl { namespace tools { TemporaryFile::TemporaryFile(std::string basename, std::string extension) { const auto extension_size = 1 + extension.size(); temp_filename_ = std::move(basename) + "_XXXXXX." + std::move(extension); const int fd = mkstemps(const_cast(temp_filename_.data()), extension_size); if (fd == -1) { ok_ = false; return; } close(fd); } TemporaryFile::~TemporaryFile() { if (ok_) { unlink(temp_filename_.c_str()); } } Status TemporaryFile::GetFileName(std::string* const output) const { JXL_RETURN_IF_ERROR(ok_); *output = temp_filename_; return true; } std::string GetBaseName(std::string filename) { std::string result = std::move(filename); result = basename(const_cast(result.data())); const size_t dot = result.rfind('.'); if (dot != std::string::npos) { result.resize(dot); } return result; } Status RunCommand(const std::string& command, const std::vector& arguments, bool quiet) { std::vector args; args.reserve(arguments.size() + 2); args.push_back(const_cast(command.c_str())); for (const std::string& argument : arguments) { args.push_back(const_cast(argument.c_str())); } args.push_back(nullptr); pid_t pid; posix_spawn_file_actions_t file_actions; posix_spawn_file_actions_init(&file_actions); if (quiet) { posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO); posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO); } JXL_RETURN_IF_ERROR(posix_spawnp(&pid, command.c_str(), &file_actions, nullptr, args.data(), environ) == 0); int wstatus; waitpid(pid, &wstatus, 0); posix_spawn_file_actions_destroy(&file_actions); return WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == EXIT_SUCCESS; } } // namespace tools } // namespace jpegxl #else namespace jpegxl { namespace tools { TemporaryFile::TemporaryFile(std::string basename, std::string extension) {} TemporaryFile::~TemporaryFile() {} Status TemporaryFile::GetFileName(std::string* const output) const { (void)ok_; return JXL_FAILURE("Not supported on this build"); } std::string GetBaseName(std::string filename) { return filename; } Status RunCommand(const std::string& command, const std::vector& arguments, bool quiet) { return JXL_FAILURE("Not supported on this build"); } } // namespace tools } // namespace jpegxl #endif // _MSC_VER