1 | //===-- ProcessLaunchInfo.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_HOST_PROCESSLAUNCHINFO_H |
10 | #define LLDB_HOST_PROCESSLAUNCHINFO_H |
11 | |
12 | // C++ Headers |
13 | #include <string> |
14 | |
15 | // LLDB Headers |
16 | #include "lldb/Utility/Flags.h" |
17 | |
18 | #include "lldb/Host/FileAction.h" |
19 | #include "lldb/Host/Host.h" |
20 | #include "lldb/Host/PseudoTerminal.h" |
21 | #include "lldb/Utility/FileSpec.h" |
22 | #include "lldb/Utility/ProcessInfo.h" |
23 | |
24 | namespace lldb_private { |
25 | |
26 | // ProcessLaunchInfo |
27 | // |
28 | // Describes any information that is required to launch a process. |
29 | |
30 | class ProcessLaunchInfo : public ProcessInfo { |
31 | public: |
32 | ProcessLaunchInfo(); |
33 | |
34 | ProcessLaunchInfo(const FileSpec &stdin_file_spec, |
35 | const FileSpec &stdout_file_spec, |
36 | const FileSpec &stderr_file_spec, |
37 | const FileSpec &working_dir, uint32_t launch_flags); |
38 | |
39 | void AppendFileAction(const FileAction &info) { |
40 | m_file_actions.push_back(x: info); |
41 | } |
42 | |
43 | bool AppendCloseFileAction(int fd); |
44 | |
45 | bool AppendDuplicateFileAction(int fd, int dup_fd); |
46 | |
47 | bool AppendOpenFileAction(int fd, const FileSpec &file_spec, bool read, |
48 | bool write); |
49 | |
50 | bool AppendSuppressFileAction(int fd, bool read, bool write); |
51 | |
52 | // Redirect stdin/stdout/stderr to a pty, if no action for the respective file |
53 | // descriptor is specified. (So if stdin and stdout already have file actions, |
54 | // but stderr doesn't, then only stderr will be redirected to a pty.) |
55 | llvm::Error SetUpPtyRedirection(); |
56 | |
57 | size_t GetNumFileActions() const { return m_file_actions.size(); } |
58 | |
59 | const FileAction *GetFileActionAtIndex(size_t idx) const; |
60 | |
61 | const FileAction *GetFileActionForFD(int fd) const; |
62 | |
63 | Flags &GetFlags() { return m_flags; } |
64 | |
65 | const Flags &GetFlags() const { return m_flags; } |
66 | |
67 | const FileSpec &GetWorkingDirectory() const; |
68 | |
69 | void SetWorkingDirectory(const FileSpec &working_dir); |
70 | |
71 | llvm::StringRef GetProcessPluginName() const; |
72 | |
73 | void SetProcessPluginName(llvm::StringRef plugin); |
74 | |
75 | const FileSpec &GetShell() const; |
76 | |
77 | void SetShell(const FileSpec &shell); |
78 | |
79 | uint32_t GetResumeCount() const { return m_resume_count; } |
80 | |
81 | void SetResumeCount(uint32_t c) { m_resume_count = c; } |
82 | |
83 | bool GetLaunchInSeparateProcessGroup() const { |
84 | return m_flags.Test(bit: lldb::eLaunchFlagLaunchInSeparateProcessGroup); |
85 | } |
86 | |
87 | void SetLaunchInSeparateProcessGroup(bool separate); |
88 | |
89 | bool GetShellExpandArguments() const { |
90 | return m_flags.Test(bit: lldb::eLaunchFlagShellExpandArguments); |
91 | } |
92 | |
93 | void SetShellExpandArguments(bool expand); |
94 | |
95 | void Clear(); |
96 | |
97 | bool ConvertArgumentsForLaunchingInShell(Status &error, bool will_debug, |
98 | bool first_arg_is_full_shell_command, |
99 | uint32_t num_resumes); |
100 | |
101 | void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback) { |
102 | m_monitor_callback = std::move(callback); |
103 | } |
104 | |
105 | const Host::MonitorChildProcessCallback &GetMonitorProcessCallback() const { |
106 | return m_monitor_callback; |
107 | } |
108 | |
109 | /// A Monitor callback which does not take any action on process events. Use |
110 | /// this if you don't need to take any particular action when the process |
111 | /// terminates, but you still need to reap it. |
112 | static void NoOpMonitorCallback(lldb::pid_t pid, int signal, int status); |
113 | |
114 | // If the LaunchInfo has a monitor callback, then arrange to monitor the |
115 | // process. Return true if the LaunchInfo has taken care of monitoring the |
116 | // process, and false if the caller might want to monitor the process |
117 | // themselves. |
118 | |
119 | bool MonitorProcess() const; |
120 | |
121 | PseudoTerminal &GetPTY() { return *m_pty; } |
122 | |
123 | void SetLaunchEventData(const char *data) { m_event_data.assign(s: data); } |
124 | |
125 | const char *GetLaunchEventData() const { return m_event_data.c_str(); } |
126 | |
127 | void SetDetachOnError(bool enable); |
128 | |
129 | bool GetDetachOnError() const { |
130 | return m_flags.Test(bit: lldb::eLaunchFlagDetachOnError); |
131 | } |
132 | |
133 | protected: |
134 | FileSpec m_working_dir; |
135 | std::string m_plugin_name; |
136 | FileSpec m_shell; |
137 | Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags |
138 | std::vector<FileAction> m_file_actions; // File actions for any other files |
139 | std::shared_ptr<PseudoTerminal> m_pty; |
140 | uint32_t m_resume_count = 0; // How many times do we resume after launching |
141 | Host::MonitorChildProcessCallback m_monitor_callback; |
142 | std::string m_event_data; // A string passed to the plugin launch, having no |
143 | // meaning to the upper levels of lldb. |
144 | }; |
145 | } |
146 | |
147 | #endif // LLDB_HOST_PROCESSLAUNCHINFO_H |
148 | |