// Copyright (C) 2019 The Android Open Source Project // // 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. // // This file is automatically generated by gen_amalgamated. Do not edit. // gen_amalgamated: predefined macros #if !defined(PERFETTO_IMPLEMENTATION) #define PERFETTO_IMPLEMENTATION #endif #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER) #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER #endif #if !defined(GOOGLE_PROTOBUF_NO_RTTI) #define GOOGLE_PROTOBUF_NO_RTTI #endif #include "perfetto.h" // gen_amalgamated begin source: src/base/ctrl_c_handler.cc // gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h /* * Copyright (C) 2021 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_ #define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_ namespace perfetto { namespace base { // On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers. // On Windows: installs a SetConsoleCtrlHandler() handler. // The passed handler must be async safe. using CtrlCHandlerFunction = void (*)(); void InstallCtrCHandler(CtrlCHandlerFunction); } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_ /* * Copyright (C) 2021 The Android Open Source Project * * 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. */ // gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h" // gen_amalgamated expanded: #include "perfetto/base/build_config.h" // gen_amalgamated expanded: #include "perfetto/base/compiler.h" // gen_amalgamated expanded: #include "perfetto/base/logging.h" #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) #include #include #else #include #include #endif namespace perfetto { namespace base { namespace { CtrlCHandlerFunction g_handler = nullptr; } void InstallCtrCHandler(CtrlCHandlerFunction handler) { PERFETTO_CHECK(g_handler == nullptr); g_handler = handler; #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) auto trampoline = [](DWORD type) -> int { if (type == CTRL_C_EVENT) { g_handler(); return true; } return false; }; ::SetConsoleCtrlHandler(trampoline, true); #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) // Setup signal handler. struct sigaction sa {}; // Glibc headers for sa_sigaction trigger this. #pragma GCC diagnostic push #if defined(__clang__) #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" #endif sa.sa_handler = [](int) { g_handler(); }; sa.sa_flags = static_cast(SA_RESETHAND | SA_RESTART); #pragma GCC diagnostic pop sigaction(SIGINT, &sa, nullptr); sigaction(SIGTERM, &sa, nullptr); #else // Do nothing on NaCL and Fuchsia. ignore_result(handler); #endif } } // namespace base } // namespace perfetto // gen_amalgamated begin source: src/base/event_fd.cc // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h // gen_amalgamated begin header: include/perfetto/base/platform_handle.h /* * Copyright (C) 2020 The Android Open Source Project * * 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 INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_ #define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_ // gen_amalgamated expanded: #include "perfetto/base/build_config.h" namespace perfetto { namespace base { // PlatformHandle should be used only for types that are HANDLE(s) in Windows. // It should NOT be used to blanket-replace "int fd" in the codebase. // Windows has two types of "handles", which, in UNIX-land, both map to int: // 1. File handles returned by the posix-compatibility API like _open(). // These are just int(s) and should stay such, because all the posix-like API // in Windows.h take an int, not a HANDLE. // 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc. // These are proper HANDLE(s). PlatformHandle should be used here. #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking // Windows.h through our headers. using PlatformHandle = void*; // On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid. struct PlatformHandleChecker { static inline bool IsValid(PlatformHandle h) { return h && h != reinterpret_cast(-1); } }; #else using PlatformHandle = int; struct PlatformHandleChecker { static inline bool IsValid(PlatformHandle h) { return h >= 0; } }; #endif // The definition of this lives in base/file_utils.cc (to avoid creating an // extra build edge for a one liner). This is really an alias for close() (UNIX) // CloseHandle() (Windows). THe indirection layer is just to avoid leaking // system headers like Windows.h through perfetto headers. // Thre return value is always UNIX-style: 0 on success, -1 on failure. int ClosePlatformHandle(PlatformHandle); } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_ // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h /* * Copyright (C) 2017 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_ #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_ // gen_amalgamated expanded: #include "perfetto/base/build_config.h" #include #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) #include // For DIR* / opendir(). #endif #include // gen_amalgamated expanded: #include "perfetto/base/export.h" // gen_amalgamated expanded: #include "perfetto/base/logging.h" // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h" namespace perfetto { namespace base { namespace internal { // Used for the most common cases of ScopedResource where there is only one // invalid value. template struct DefaultValidityChecker { static bool IsValid(T t) { return t != InvalidValue; } }; } // namespace internal // RAII classes for auto-releasing fds and dirs. // if T is a pointer type, InvalidValue must be nullptr. Doing otherwise // causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4). template > class PERFETTO_EXPORT ScopedResource { public: using ValidityChecker = Checker; static constexpr T kInvalid = InvalidValue; explicit ScopedResource(T t = InvalidValue) : t_(t) {} ScopedResource(ScopedResource&& other) noexcept { t_ = other.t_; other.t_ = InvalidValue; } ScopedResource& operator=(ScopedResource&& other) { reset(other.t_); other.t_ = InvalidValue; return *this; } T get() const { return t_; } T operator*() const { return t_; } explicit operator bool() const { return Checker::IsValid(t_); } void reset(T r = InvalidValue) { if (Checker::IsValid(t_)) { int res = CloseFunction(t_); if (CheckClose) PERFETTO_CHECK(res == 0); } t_ = r; } T release() { T t = t_; t_ = InvalidValue; return t; } ~ScopedResource() { reset(InvalidValue); } private: ScopedResource(const ScopedResource&) = delete; ScopedResource& operator=(const ScopedResource&) = delete; T t_; }; // Declared in file_utils.h. Forward declared to avoid #include cycles. int PERFETTO_EXPORT CloseFile(int fd); // Use this for file resources obtained via open() and similar APIs. using ScopedFile = ScopedResource; using ScopedFstream = ScopedResource; // Use this for resources that are HANDLE on Windows. See comments in // platform_handle.h #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) using ScopedPlatformHandle = ScopedResource; #else // On non-windows systems we alias ScopedPlatformHandle to ScopedFile because // they are really the same. This is to allow assignments between the two in // Linux-specific code paths that predate ScopedPlatformHandle. static_assert(std::is_same::value, ""); using ScopedPlatformHandle = ScopedFile; // DIR* does not exist on Windows. using ScopedDir = ScopedResource; #endif } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_ /* * Copyright (C) 2018 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_ #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_ // gen_amalgamated expanded: #include "perfetto/base/build_config.h" // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h" // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h" namespace perfetto { namespace base { // A waitable event that can be used with poll/select. // This is really a wrapper around eventfd_create with a pipe-based fallback // for other platforms where eventfd is not supported. class EventFd { public: EventFd(); ~EventFd(); EventFd(EventFd&&) noexcept = default; EventFd& operator=(EventFd&&) = default; // The non-blocking file descriptor that can be polled to wait for the event. PlatformHandle fd() const { return event_handle_.get(); } // Can be called from any thread. void Notify(); // Can be called from any thread. If more Notify() are queued a Clear() call // can clear all of them (up to 16 per call). void Clear(); private: // The eventfd, when eventfd is supported, otherwise this is the read end of // the pipe for fallback mode. ScopedPlatformHandle event_handle_; #if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) && \ !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \ !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used. // The write end of the wakeup pipe. ScopedFile write_fd_; #endif }; } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_ // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h /* * Copyright (C) 2018 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_PIPE_H_ #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_ // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h" // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h" namespace perfetto { namespace base { class Pipe { public: enum Flags { kBothBlock = 0, #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) kBothNonBlock, kRdNonBlock, kWrNonBlock, #endif }; static Pipe Create(Flags = kBothBlock); Pipe(); Pipe(Pipe&&) noexcept; Pipe& operator=(Pipe&&); ScopedPlatformHandle rd; ScopedPlatformHandle wr; }; } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_ // gen_amalgamated begin header: include/perfetto/ext/base/utils.h /* * Copyright (C) 2017 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_UTILS_H_ #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_ // gen_amalgamated expanded: #include "perfetto/base/build_config.h" // gen_amalgamated expanded: #include "perfetto/base/compiler.h" #include #include #include #include #include #include #include #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // Even if Windows has errno.h, the all syscall-restart behavior does not apply. // Trying to handle EINTR can cause more harm than good if errno is left stale. // Chromium does the same. #define PERFETTO_EINTR(x) (x) #else #define PERFETTO_EINTR(x) \ ([&] { \ decltype(x) eintr_wrapper_result; \ do { \ eintr_wrapper_result = (x); \ } while (eintr_wrapper_result == -1 && errno == EINTR); \ return eintr_wrapper_result; \ }()) #endif #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) using uid_t = unsigned int; #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC) using pid_t = unsigned int; #endif #if defined(_WIN64) using ssize_t = int64_t; #else using ssize_t = long; #endif #endif namespace perfetto { namespace base { constexpr uid_t kInvalidUid = static_cast(-1); constexpr pid_t kInvalidPid = static_cast(-1); // Do not add new usages of kPageSize, consider using GetSysPageSize() below. // TODO(primiano): over time the semantic of kPageSize became too ambiguous. // Strictly speaking, this constant is incorrect on some new devices where the // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code // ended up depending on kPageSize for purposes that are not strictly related // with the kernel's mm subsystem. constexpr size_t kPageSize = 4096; // Returns the system's page size. Use this when dealing with mmap, madvise and // similar mm-related syscalls. uint32_t GetSysPageSize(); template constexpr size_t ArraySize(const T& array) { return sizeof(array) / sizeof(array[0]); } // Function object which invokes 'free' on its parameter, which must be // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr: // // std::unique_ptr foo_ptr( // static_cast(malloc(sizeof(int)))); struct FreeDeleter { inline void operator()(void* ptr) const { free(ptr); } }; template constexpr T AssumeLittleEndian(T value) { #if !PERFETTO_IS_LITTLE_ENDIAN() static_assert(false, "Unimplemented on big-endian archs"); #endif return value; } // Round up |size| to a multiple of |alignment| (must be a power of two). template constexpr size_t AlignUp(size_t size) { static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2"); return (size + alignment - 1) & ~(alignment - 1); } inline bool IsAgain(int err) { return err == EAGAIN || err == EWOULDBLOCK; } // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies. void SetEnv(const std::string& key, const std::string& value); // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms. // This forces the allocator to release freed memory. This is used to work // around various Scudo inefficiencies. See b/170217718. void MaybeReleaseAllocatorMemToOS(); // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc). uid_t GetCurrentUserId(); // Forks the process. // Parent: prints the PID of the child and exit(0). // Child: redirects stdio onto /dev/null and chdirs into . void Daemonize(); } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_ /* * Copyright (C) 2018 The Android Open Source Project * * 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. */ // gen_amalgamated expanded: #include "perfetto/base/build_config.h" #include #include #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) #include #include #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) #include #include #else // Mac, Fuchsia and other non-Linux UNIXes #include #endif // gen_amalgamated expanded: #include "perfetto/base/logging.h" // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h" // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h" // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h" namespace perfetto { namespace base { EventFd::~EventFd() = default; #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) EventFd::EventFd() { event_handle_.reset( CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true, /*bInitialState=*/false, /*bInitialState=*/nullptr)); } void EventFd::Notify() { if (!SetEvent(event_handle_.get())) // 0: fail, !0: success, unlike UNIX. PERFETTO_DFATAL("EventFd::Notify()"); } void EventFd::Clear() { if (!ResetEvent(event_handle_.get())) // 0: fail, !0: success, unlike UNIX. PERFETTO_DFATAL("EventFd::Clear()"); } #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) EventFd::EventFd() { event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK)); PERFETTO_CHECK(event_handle_); } void EventFd::Notify() { const uint64_t value = 1; ssize_t ret = write(event_handle_.get(), &value, sizeof(value)); if (ret <= 0 && errno != EAGAIN) PERFETTO_DFATAL("EventFd::Notify()"); } void EventFd::Clear() { uint64_t value; ssize_t ret = read(event_handle_.get(), &value, sizeof(value)); if (ret <= 0 && errno != EAGAIN) PERFETTO_DFATAL("EventFd::Clear()"); } #else EventFd::EventFd() { // Make the pipe non-blocking so that we never block the waking thread (either // the main thread or another one) when scheduling a wake-up. Pipe pipe = Pipe::Create(Pipe::kBothNonBlock); event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release()); write_fd_ = std::move(pipe.wr); } void EventFd::Notify() { const uint64_t value = 1; ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t)); if (ret <= 0 && errno != EAGAIN) PERFETTO_DFATAL("EventFd::Notify()"); } void EventFd::Clear() { // Drain the byte(s) written to the wake-up pipe. We can potentially read // more than one byte if several wake-ups have been scheduled. char buffer[16]; ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer)); if (ret <= 0 && errno != EAGAIN) PERFETTO_DFATAL("EventFd::Clear()"); } #endif } // namespace base } // namespace perfetto // gen_amalgamated begin source: src/base/file_utils.cc // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h /* * Copyright (C) 2018 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_ #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_ #include // For mode_t & O_RDONLY/RDWR. Exists also on Windows. #include #include // gen_amalgamated expanded: #include "perfetto/base/build_config.h" // gen_amalgamated expanded: #include "perfetto/base/export.h" // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h" // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h" namespace perfetto { namespace base { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) using FileOpenMode = int; #else using FileOpenMode = mode_t; #endif constexpr FileOpenMode kFileModeInvalid = static_cast(-1); bool ReadPlatformHandle(PlatformHandle, std::string* out); bool ReadFileDescriptor(int fd, std::string* out); bool ReadFileStream(FILE* f, std::string* out); bool ReadFile(const std::string& path, std::string* out); // A wrapper around read(2). It deals with Linux vs Windows includes. It also // deals with handling EINTR. Has the same semantics of UNIX's read(2). ssize_t Read(int fd, void* dst, size_t dst_size); // Call write until all data is written or an error is detected. // // man 2 write: // If a write() is interrupted by a signal handler before any bytes are // written, then the call fails with the error EINTR; if it is // interrupted after at least one byte has been written, the call // succeeds, and returns the number of bytes written. ssize_t WriteAll(int fd, const void* buf, size_t count); ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count); ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode = kFileModeInvalid); // This is an alias for close(). It's to avoid leaking Windows.h in headers. // Exported because ScopedFile is used in the /include/ext API by Chromium // component builds. int PERFETTO_EXPORT CloseFile(int fd); bool FlushFile(int fd); // Returns true if mkdir succeeds, false if it fails (see errno in that case). bool Mkdir(const std::string& path); // Calls rmdir() on UNIX, _rmdir() on Windows. bool Rmdir(const std::string& path); // Wrapper around access(path, F_OK). bool FileExists(const std::string& path); } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_ /* * Copyright (C) 2018 The Android Open Source Project * * 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. */ // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h" #include #include #include // gen_amalgamated expanded: #include "perfetto/base/build_config.h" // gen_amalgamated expanded: #include "perfetto/base/logging.h" // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h" // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h" // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h" #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) #include #include #include #else #include #include #endif namespace perfetto { namespace base { namespace { constexpr size_t kBufSize = 2048; } ssize_t Read(int fd, void* dst, size_t dst_size) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) return _read(fd, dst, static_cast(dst_size)); #else return PERFETTO_EINTR(read(fd, dst, dst_size)); #endif } bool ReadFileDescriptor(int fd, std::string* out) { // Do not override existing data in string. size_t i = out->size(); struct stat buf {}; if (fstat(fd, &buf) != -1) { if (buf.st_size > 0) out->resize(i + static_cast(buf.st_size)); } ssize_t bytes_read; for (;;) { if (out->size() < i + kBufSize) out->resize(out->size() + kBufSize); bytes_read = Read(fd, &((*out)[i]), kBufSize); if (bytes_read > 0) { i += static_cast(bytes_read); } else { out->resize(i); return bytes_read == 0; } } } bool ReadPlatformHandle(PlatformHandle h, std::string* out) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // Do not override existing data in string. size_t i = out->size(); for (;;) { if (out->size() < i + kBufSize) out->resize(out->size() + kBufSize); DWORD bytes_read = 0; auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr); if (res && bytes_read > 0) { i += static_cast(bytes_read); } else { out->resize(i); const bool is_eof = res && bytes_read == 0; auto err = res ? 0 : GetLastError(); // The "Broken pipe" error on Windows is slighly different than Unix: // On Unix: a "broken pipe" error can happen only on the writer side. On // the reader there is no broken pipe, just a EOF. // On windows: the reader also sees a broken pipe error. // Here we normalize on the Unix behavior, treating broken pipe as EOF. return is_eof || err == ERROR_BROKEN_PIPE; } } #else return ReadFileDescriptor(h, out); #endif } bool ReadFileStream(FILE* f, std::string* out) { return ReadFileDescriptor(fileno(f), out); } bool ReadFile(const std::string& path, std::string* out) { base::ScopedFile fd = base::OpenFile(path, O_RDONLY); if (!fd) return false; return ReadFileDescriptor(*fd, out); } ssize_t WriteAll(int fd, const void* buf, size_t count) { size_t written = 0; while (written < count) { // write() on windows takes an unsigned int size. uint32_t bytes_left = static_cast( std::min(count - written, static_cast(UINT32_MAX))); ssize_t wr = PERFETTO_EINTR( write(fd, static_cast(buf) + written, bytes_left)); if (wr == 0) break; if (wr < 0) return wr; written += static_cast(wr); } return static_cast(written); } ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) DWORD wsize = 0; if (::WriteFile(h, buf, static_cast(count), &wsize, nullptr)) { return wsize; } else { return -1; } #else return WriteAll(h, buf, count); #endif } bool FlushFile(int fd) { PERFETTO_DCHECK(fd != 0); #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) return !PERFETTO_EINTR(fdatasync(fd)); #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) return !PERFETTO_EINTR(_commit(fd)); #else return !PERFETTO_EINTR(fsync(fd)); #endif } bool Mkdir(const std::string& path) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) return _mkdir(path.c_str()) == 0; #else return mkdir(path.c_str(), 0755) == 0; #endif } bool Rmdir(const std::string& path) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) return _rmdir(path.c_str()) == 0; #else return rmdir(path.c_str()) == 0; #endif } int CloseFile(int fd) { return close(fd); } ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) { PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid); #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // Always use O_BINARY on Windows, to avoid silly EOL translations. ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode)); #else // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec. ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode)); #endif return fd; } bool FileExists(const std::string& path) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) return _access(path.c_str(), 0) == 0; #else return access(path.c_str(), F_OK) == 0; #endif } // Declared in base/platform_handle.h. int ClosePlatformHandle(PlatformHandle handle) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) // Make the return value UNIX-style. return CloseHandle(handle) ? 0 : -1; #else return close(handle); #endif } } // namespace base } // namespace perfetto // gen_amalgamated begin source: src/base/getopt_compat.cc // gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h /* * Copyright (C) 2021 The Android Open Source Project * * 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 INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_ #define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_ #include // For std::nullptr_t // No translation units other than base/getopt.h and getopt_compat_unittest.cc // should directly include this file. Use base/getopt.h instead. namespace perfetto { namespace base { namespace getopt_compat { // A tiny getopt() replacement for Windows, which doesn't have . // This implementation is based on the subset of features that we use in the // Perfetto codebase. It doesn't even try to deal with the full surface of GNU's // getopt(). // Limitations: // - getopt_long_only() is not supported. // - optional_argument is not supported. That is extremely subtle and caused us // problems in the past with GNU's getopt. // - It does not reorder non-option arguments. It behaves like MacOS getopt, or // GNU's when POSIXLY_CORRECT=1. // - Doesn't expose optopt or opterr. // - option.flag and longindex are not supported and must be nullptr. enum { no_argument = 0, required_argument = 1, }; struct option { const char* name; int has_arg; std::nullptr_t flag; // Only nullptr is supported. int val; }; extern char* optarg; extern int optind; int getopt_long(int argc, char** argv, const char* shortopts, const option* longopts, std::nullptr_t /*longindex is not supported*/); int getopt(int argc, char** argv, const char* shortopts); } // namespace getopt_compat } // namespace base } // namespace perfetto #endif // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_ /* * Copyright (C) 2021 The Android Open Source Project * * 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. */ // gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h" #include #include #include #include // gen_amalgamated expanded: #include "perfetto/base/logging.h" namespace perfetto { namespace base { namespace getopt_compat { char* optarg = nullptr; int optind = 0; namespace { char* nextchar = nullptr; const option* LookupLongOpt(const std::vector