[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / tools / lldb-dap / OutputRedirector.cpp
blob2c2f49569869b4e4abe777a24ded9d5ca9c19e97
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 //===----------------------------------------------------------------------===/
9 #if defined(_WIN32)
10 #include <fcntl.h>
11 #include <io.h>
12 #else
13 #include <unistd.h>
14 #endif
16 #include "DAP.h"
17 #include "OutputRedirector.h"
18 #include "llvm/ADT/StringRef.h"
20 using namespace llvm;
22 namespace lldb_dap {
24 Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
25 int new_fd[2];
26 #if defined(_WIN32)
27 if (_pipe(new_fd, 4096, O_TEXT) == -1) {
28 #else
29 if (pipe(new_fd) == -1) {
30 #endif
31 int error = errno;
32 return createStringError(inconvertibleErrorCode(),
33 "Couldn't create new pipe for fd %d. %s", fd,
34 strerror(error));
37 if (dup2(new_fd[1], fd) == -1) {
38 int error = errno;
39 return createStringError(inconvertibleErrorCode(),
40 "Couldn't override the fd %d. %s", fd,
41 strerror(error));
44 int read_fd = new_fd[0];
45 std::thread t([read_fd, callback]() {
46 char buffer[OutputBufferSize];
47 while (true) {
48 ssize_t bytes_count = read(read_fd, &buffer, sizeof(buffer));
49 if (bytes_count == 0)
50 return;
51 if (bytes_count == -1) {
52 if (errno == EAGAIN || errno == EINTR)
53 continue;
54 break;
56 callback(StringRef(buffer, bytes_count));
58 });
59 t.detach();
60 return Error::success();
63 } // namespace lldb_dap