1//===-- OutputRedirector.cpp -----------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===/
8
9#if defined(_WIN32)
10#include <fcntl.h>
11#include <io.h>
12#else
13#include <unistd.h>
14#endif
15
16#include "OutputRedirector.h"
17#include "llvm/ADT/StringRef.h"
18
19using namespace llvm;
20
21namespace lldb_dap {
22
23Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
24 int new_fd[2];
25#if defined(_WIN32)
26 if (_pipe(new_fd, 4096, O_TEXT) == -1) {
27#else
28 if (pipe(pipedes: new_fd) == -1) {
29#endif
30 int error = errno;
31 return createStringError(EC: inconvertibleErrorCode(),
32 Fmt: "Couldn't create new pipe for fd %d. %s", Vals: fd,
33 Vals: strerror(errnum: error));
34 }
35
36 if (dup2(fd: new_fd[1], fd2: fd) == -1) {
37 int error = errno;
38 return createStringError(EC: inconvertibleErrorCode(),
39 Fmt: "Couldn't override the fd %d. %s", Vals: fd,
40 Vals: strerror(errnum: error));
41 }
42
43 int read_fd = new_fd[0];
44 std::thread t([read_fd, callback]() {
45 char buffer[4096];
46 while (true) {
47 ssize_t bytes_count = read(fd: read_fd, buf: &buffer, nbytes: sizeof(buffer));
48 if (bytes_count == 0)
49 return;
50 if (bytes_count == -1) {
51 if (errno == EAGAIN || errno == EINTR)
52 continue;
53 break;
54 }
55 callback(StringRef(buffer, bytes_count));
56 }
57 });
58 t.detach();
59 return Error::success();
60}
61
62} // namespace lldb_dap
63

source code of lldb/tools/lldb-dap/OutputRedirector.cpp