1 //===-- RunInTerminal.h ----------------------------------------*- 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 #ifndef LLDB_TOOLS_LLDB_VSCODE_RUNINTERMINAL_H
10 #define LLDB_TOOLS_LLDB_VSCODE_RUNINTERMINAL_H
11 
12 #include "FifoFiles.h"
13 
14 #include <future>
15 #include <thread>
16 
17 namespace lldb_vscode {
18 
19 enum RunInTerminalMessageKind {
20   eRunInTerminalMessageKindPID = 0,
21   eRunInTerminalMessageKindError,
22   eRunInTerminalMessageKindDidAttach,
23 };
24 
25 struct RunInTerminalMessage;
26 struct RunInTerminalMessagePid;
27 struct RunInTerminalMessageError;
28 struct RunInTerminalMessageDidAttach;
29 
30 struct RunInTerminalMessage {
31   RunInTerminalMessage(RunInTerminalMessageKind kind);
32 
33   virtual ~RunInTerminalMessage() = default;
34 
35   /// Serialize this object to JSON
36   virtual llvm::json::Value ToJSON() const = 0;
37 
38   const RunInTerminalMessagePid *GetAsPidMessage() const;
39 
40   const RunInTerminalMessageError *GetAsErrorMessage() const;
41 
42   RunInTerminalMessageKind kind;
43 };
44 
45 using RunInTerminalMessageUP = std::unique_ptr<RunInTerminalMessage>;
46 
47 struct RunInTerminalMessagePid : RunInTerminalMessage {
48   RunInTerminalMessagePid(lldb::pid_t pid);
49 
50   llvm::json::Value ToJSON() const override;
51 
52   lldb::pid_t pid;
53 };
54 
55 struct RunInTerminalMessageError : RunInTerminalMessage {
56   RunInTerminalMessageError(llvm::StringRef error);
57 
58   llvm::json::Value ToJSON() const override;
59 
60   std::string error;
61 };
62 
63 struct RunInTerminalMessageDidAttach : RunInTerminalMessage {
64   RunInTerminalMessageDidAttach();
65 
66   llvm::json::Value ToJSON() const override;
67 };
68 
69 class RunInTerminalLauncherCommChannel {
70 public:
71   RunInTerminalLauncherCommChannel(llvm::StringRef comm_file);
72 
73   /// Wait until the debug adaptor attaches.
74   ///
75   /// \param[in] timeout
76   ///     How long to wait to be attached.
77   //
78   /// \return
79   ///     An \a llvm::Error object in case of errors or if this operation times
80   ///     out.
81   llvm::Error WaitUntilDebugAdaptorAttaches(std::chrono::milliseconds timeout);
82 
83   /// Notify the debug adaptor this process' pid.
84   ///
85   /// \return
86   ///     An \a llvm::Error object in case of errors or if this operation times
87   ///     out.
88   llvm::Error NotifyPid();
89 
90   /// Notify the debug adaptor that there's been an error.
91   void NotifyError(llvm::StringRef error);
92 
93 private:
94   FifoFileIO m_io;
95 };
96 
97 class RunInTerminalDebugAdapterCommChannel {
98 public:
99   RunInTerminalDebugAdapterCommChannel(llvm::StringRef comm_file);
100 
101   /// Notify the runInTerminal launcher that it was attached.
102   ///
103   /// \return
104   ///     A future indicated whether the runInTerminal launcher received the
105   ///     message correctly or not.
106   std::future<lldb::SBError> NotifyDidAttach();
107 
108   /// Fetch the pid of the runInTerminal launcher.
109   ///
110   /// \return
111   ///     An \a llvm::Error object in case of errors or if this operation times
112   ///     out.
113   llvm::Expected<lldb::pid_t> GetLauncherPid();
114 
115   /// Fetch any errors emitted by the runInTerminal launcher or return a
116   /// default error message if a certain timeout if reached.
117   std::string GetLauncherError();
118 
119 private:
120   FifoFileIO m_io;
121 };
122 
123 /// Create a fifo file used to communicate the debug adaptor with
124 /// the runInTerminal launcher.
125 llvm::Expected<std::shared_ptr<FifoFile>> CreateRunInTerminalCommFile();
126 
127 } // namespace lldb_vscode
128 
129 #endif // LLDB_TOOLS_LLDB_VSCODE_RUNINTERMINAL_H
130