blob: 7432a828d045b8e88775f1ef548a9c1dccb0be52 [file] [log] [blame]
//===-- OutputRedirector.cpp -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===/
#if !defined(_WIN32)
#include <unistd.h>
#endif
#include "OutputRedirector.h"
using namespace llvm;
namespace lldb_vscode {
Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
#if !defined(_WIN32)
int new_fd[2];
if (pipe(new_fd) == -1) {
int error = errno;
return createStringError(inconvertibleErrorCode(),
"Couldn't create new pipe for fd %d. %s", fd,
strerror(error));
}
if (dup2(new_fd[1], fd) == -1) {
int error = errno;
return createStringError(inconvertibleErrorCode(),
"Couldn't override the fd %d. %s", fd,
strerror(error));
}
int read_fd = new_fd[0];
std::thread t([read_fd, callback]() {
char buffer[4096];
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;
break;
}
callback(StringRef(buffer, bytes_count).str());
}
});
t.detach();
#endif
return Error::success();
}
} // namespace lldb_vscode