benchmark_utils.cc (3231B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #define _DEFAULT_SOURCE // for mkstemps(). 7 8 #include "tools/benchmark/benchmark_utils.h" 9 10 // Not supported on Windows due to Linux-specific functions. 11 // Not supported in Android NDK before API 28. 12 #if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && \ 13 (!defined(__ANDROID_API__) || __ANDROID_API__ >= 28) 14 15 #include <libgen.h> 16 #include <spawn.h> 17 #include <stdio.h> 18 #include <sys/types.h> 19 #include <sys/wait.h> 20 #include <unistd.h> 21 22 #include <fstream> 23 24 #include "lib/jxl/image_bundle.h" 25 #include "tools/file_io.h" 26 27 extern char** environ; // NOLINT 28 29 namespace jpegxl { 30 namespace tools { 31 TemporaryFile::TemporaryFile(std::string basename, std::string extension) { 32 const auto extension_size = 1 + extension.size(); 33 temp_filename_ = std::move(basename) + "_XXXXXX." + std::move(extension); 34 const int fd = 35 mkstemps(const_cast<char*>(temp_filename_.data()), extension_size); 36 if (fd == -1) { 37 ok_ = false; 38 return; 39 } 40 close(fd); 41 } 42 TemporaryFile::~TemporaryFile() { 43 if (ok_) { 44 unlink(temp_filename_.c_str()); 45 } 46 } 47 48 Status TemporaryFile::GetFileName(std::string* const output) const { 49 JXL_RETURN_IF_ERROR(ok_); 50 *output = temp_filename_; 51 return true; 52 } 53 54 std::string GetBaseName(std::string filename) { 55 std::string result = std::move(filename); 56 result = basename(const_cast<char*>(result.data())); 57 const size_t dot = result.rfind('.'); 58 if (dot != std::string::npos) { 59 result.resize(dot); 60 } 61 return result; 62 } 63 64 Status RunCommand(const std::string& command, 65 const std::vector<std::string>& arguments, bool quiet) { 66 std::vector<char*> args; 67 args.reserve(arguments.size() + 2); 68 args.push_back(const_cast<char*>(command.c_str())); 69 for (const std::string& argument : arguments) { 70 args.push_back(const_cast<char*>(argument.c_str())); 71 } 72 args.push_back(nullptr); 73 pid_t pid; 74 posix_spawn_file_actions_t file_actions; 75 posix_spawn_file_actions_init(&file_actions); 76 if (quiet) { 77 posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO); 78 posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO); 79 } 80 JXL_RETURN_IF_ERROR(posix_spawnp(&pid, command.c_str(), &file_actions, 81 nullptr, args.data(), environ) == 0); 82 int wstatus; 83 waitpid(pid, &wstatus, 0); 84 posix_spawn_file_actions_destroy(&file_actions); 85 return WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == EXIT_SUCCESS; 86 } 87 88 } // namespace tools 89 } // namespace jpegxl 90 91 #else 92 93 namespace jpegxl { 94 namespace tools { 95 96 TemporaryFile::TemporaryFile(std::string basename, std::string extension) {} 97 TemporaryFile::~TemporaryFile() {} 98 Status TemporaryFile::GetFileName(std::string* const output) const { 99 (void)ok_; 100 return JXL_FAILURE("Not supported on this build"); 101 } 102 103 std::string GetBaseName(std::string filename) { return filename; } 104 105 Status RunCommand(const std::string& command, 106 const std::vector<std::string>& arguments, bool quiet) { 107 return JXL_FAILURE("Not supported on this build"); 108 } 109 110 } // namespace tools 111 } // namespace jpegxl 112 113 #endif // _MSC_VER