13#include "llvm/ADT/SmallString.h"
14#include "llvm/Support/Errno.h"
15#include "llvm/Support/Error.h"
17#include <system_error>
36#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
38#define PIPE2_SUPPORTED 1
40#define PIPE2_SUPPORTED 0
45#if defined(FD_CLOEXEC) && !PIPE2_SUPPORTED
46static bool SetCloexecFlag(
int fd) {
47 int flags = ::fcntl(fd, F_GETFD);
50 return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
54static std::chrono::time_point<std::chrono::steady_clock>
Now() {
55 return std::chrono::steady_clock::now();
62 :
m_fds{read, write} {}
70 std::scoped_lock<std::mutex, std::mutex, std::mutex, std::mutex> guard(
72 pipe_posix.m_write_mutex);
74 PipeBase::operator=(std::move(pipe_posix));
75 m_fds[
READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
76 m_fds[
WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
89 if (::pipe2(
m_fds, O_CLOEXEC) == 0)
92 if (::pipe(
m_fds) == 0) {
94 if (!SetCloexecFlag(
m_fds[0]) || !SetCloexecFlag(
m_fds[1])) {
116 if (::mkfifo(name.str().c_str(), 0660) != 0)
123 llvm::SmallString<128> named_pipe_path;
124 llvm::SmallString<128> pipe_spec((prefix +
".%%%%%%").str());
125 FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
126 if (!tmpdir_file_spec)
135 llvm::sys::fs::createUniquePath(tmpdir_file_spec.
GetPath(), named_pipe_path,
138 }
while (
error.GetError() == EEXIST);
141 name = named_pipe_path;
151 int flags = O_RDONLY |
O_NONBLOCK | O_CLOEXEC;
167 return llvm::createStringError(
"Pipe is already opened");
169 int flags = O_WRONLY |
O_NONBLOCK | O_CLOEXEC;
171 using namespace std::chrono;
172 std::optional<time_point<steady_clock>> finish_time;
174 finish_time =
Now() + *timeout;
178 if (
Now() > finish_time)
179 return llvm::createStringError(
180 std::make_error_code(std::errc::timed_out),
181 "timeout exceeded - reader hasn't opened so far");
185 int fd = ::open(name.str().c_str(), flags);
187 const auto errno_copy = errno;
189 if (errno_copy != ENXIO && errno_copy != EINTR)
190 return llvm::errorCodeToError(
191 std::error_code(errno_copy, std::generic_category()));
193 std::this_thread::sleep_for(
200 return llvm::Error::success();
254 return llvm::sys::fs::remove(name);
302 return llvm::errorCodeToError(
303 std::make_error_code(std::errc::invalid_argument));
315 ssize_t result = ::read(fd, buf, size);
317 return llvm::errorCodeToError(
318 std::error_code(errno, std::generic_category()));
327 return llvm::errorCodeToError(
328 std::make_error_code(std::errc::invalid_argument));
339 ssize_t result = ::write(fd, buf, size);
341 return llvm::errorCodeToError(
342 std::error_code(errno, std::generic_category()));
static llvm::raw_ostream & error(Stream &strm)
static std::chrono::time_point< std::chrono::steady_clock > Now()
static constexpr auto OPEN_WRITER_SLEEP_TIMEOUT_MSECS
lldb_private::Status Select()
void FDSetRead(lldb::socket_t fd)
void SetTimeout(const std::chrono::microseconds &timeout)
void FDSetWrite(lldb::socket_t fd)
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
llvm::Error OpenAsWriter(llvm::StringRef name, const Timeout< std::micro > &timeout) override
int ReleaseWriteFileDescriptorUnlocked()
int GetReadFileDescriptor() const override
void CloseWriteFileDescriptor() override
Status CreateNew() override
bool CanWrite() const override
bool CanRead() const override
static int kInvalidDescriptor
std::mutex m_read_mutex
Mutexes for m_fds;.
int ReleaseReadFileDescriptor() override
llvm::Expected< size_t > Read(void *buf, size_t size, const Timeout< std::micro > &timeout=std::nullopt) override
Status Delete(llvm::StringRef name) override
int ReleaseReadFileDescriptorUnlocked()
void CloseWriteFileDescriptorUnlocked()
int GetReadFileDescriptorUnlocked() const
Status OpenAsReader(llvm::StringRef name) override
bool CanWriteUnlocked() const
PipePosix & operator=(const PipePosix &)=delete
llvm::Expected< size_t > Write(const void *buf, size_t size, const Timeout< std::micro > &timeout=std::nullopt) override
int ReleaseWriteFileDescriptor() override
void CloseReadFileDescriptorUnlocked()
void CloseReadFileDescriptor() override
bool CanReadUnlocked() const
int GetWriteFileDescriptor() const override
int GetWriteFileDescriptorUnlocked() const
Status CreateWithUniqueName(llvm::StringRef prefix, llvm::SmallVectorImpl< char > &name) override
static Status FromErrno()
Set the current error to errno.
static Status FromErrorString(const char *str)
A class that represents a running process on the host machine.
@ eErrorTypePOSIX
POSIX error codes.