================ @@ -17,47 +19,59 @@ #include "OutputRedirector.h" #include "llvm/ADT/StringRef.h" -using namespace llvm; +using lldb_private::Pipe; +using lldb_private::Status; +using llvm::createStringError; +using llvm::Error; +using llvm::Expected; +using llvm::StringRef; namespace lldb_dap { -Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) { - int new_fd[2]; -#if defined(_WIN32) - if (_pipe(new_fd, 4096, O_TEXT) == -1) { -#else - if (pipe(new_fd) == -1) { -#endif - int error = errno; - return createStringError(inconvertibleErrorCode(), - "Couldn't create new pipe for fd %d. %s", fd, - strerror(error)); - } +Expected<int> OutputRedirector::GetWriteFileDescriptor() { + if (!m_pipe.CanWrite()) + return createStringError(std::errc::bad_file_descriptor, + "write handle is not open for writing"); + return m_pipe.GetWriteFileDescriptor(); +} - if (dup2(new_fd[1], fd) == -1) { - int error = errno; - return createStringError(inconvertibleErrorCode(), - "Couldn't override the fd %d. %s", fd, - strerror(error)); - } +Error OutputRedirector::RedirectTo(std::function<void(StringRef)> callback) { + Status status = m_pipe.CreateNew(/*child_process_inherit=*/false); + if (status.Fail()) + return status.takeError(); - int read_fd = new_fd[0]; - std::thread t([read_fd, callback]() { + m_forwarder = std::thread([this, callback]() { char buffer[OutputBufferSize]; - while (true) { - ssize_t bytes_count = read(read_fd, &buffer, sizeof(buffer)); - if (bytes_count == 0) - return; - if (bytes_count == -1) { - if (errno == EAGAIN || errno == EINTR) - continue; + while (m_pipe.CanRead() && !m_stopped) { + size_t bytes_read; + Status status = m_pipe.Read(&buffer, sizeof(buffer), bytes_read); + if (status.Fail()) + continue; + + // EOF detected + if (bytes_read == 0) break; - } - callback(StringRef(buffer, bytes_count)); + + callback(StringRef(buffer, bytes_read)); } }); - t.detach(); + return Error::success(); } +void OutputRedirector::Stop() { + m_stopped = true; + + if (m_pipe.CanWrite()) { + // If the fd is waiting for input and is closed it may not return from the + // current select/poll/kqueue/etc. asyncio wait operation. Write a null byte + // to ensure the read fd wakes to detect the closed FD. ---------------- ashgti wrote:
Done https://github.com/llvm/llvm-project/pull/120457 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits