1351290Sdim//===-- ProcessLaunchInfo.h -------------------------------------*- C++ -*-===//
2351290Sdim//
3351290Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4351290Sdim// See https://llvm.org/LICENSE.txt for license information.
5351290Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6351290Sdim//
7351290Sdim//===----------------------------------------------------------------------===//
8351290Sdim
9351290Sdim#ifndef liblldb_ProcessLaunch_Info_h
10351290Sdim#define liblldb_ProcessLaunch_Info_h
11351290Sdim
12351290Sdim// C++ Headers
13351290Sdim#include <string>
14351290Sdim
15351290Sdim// LLDB Headers
16351290Sdim#include "lldb/Utility/Flags.h"
17351290Sdim
18351290Sdim#include "lldb/Host/FileAction.h"
19351290Sdim#include "lldb/Host/Host.h"
20351290Sdim#include "lldb/Host/PseudoTerminal.h"
21351290Sdim#include "lldb/Utility/FileSpec.h"
22351290Sdim#include "lldb/Utility/ProcessInfo.h"
23351290Sdim
24351290Sdimnamespace lldb_private {
25351290Sdim
26351290Sdim// ProcessLaunchInfo
27351290Sdim//
28351290Sdim// Describes any information that is required to launch a process.
29351290Sdim
30351290Sdimclass ProcessLaunchInfo : public ProcessInfo {
31351290Sdimpublic:
32351290Sdim  ProcessLaunchInfo();
33351290Sdim
34351290Sdim  ProcessLaunchInfo(const FileSpec &stdin_file_spec,
35351290Sdim                    const FileSpec &stdout_file_spec,
36351290Sdim                    const FileSpec &stderr_file_spec,
37351290Sdim                    const FileSpec &working_dir, uint32_t launch_flags);
38351290Sdim
39351290Sdim  void AppendFileAction(const FileAction &info) {
40351290Sdim    m_file_actions.push_back(info);
41351290Sdim  }
42351290Sdim
43351290Sdim  bool AppendCloseFileAction(int fd);
44351290Sdim
45351290Sdim  bool AppendDuplicateFileAction(int fd, int dup_fd);
46351290Sdim
47351290Sdim  bool AppendOpenFileAction(int fd, const FileSpec &file_spec, bool read,
48351290Sdim                            bool write);
49351290Sdim
50351290Sdim  bool AppendSuppressFileAction(int fd, bool read, bool write);
51351290Sdim
52351290Sdim  // Redirect stdin/stdout/stderr to a pty, if no action for the respective file
53351290Sdim  // descriptor is specified. (So if stdin and stdout already have file actions,
54351290Sdim  // but stderr doesn't, then only stderr will be redirected to a pty.)
55351290Sdim  llvm::Error SetUpPtyRedirection();
56351290Sdim
57351290Sdim  size_t GetNumFileActions() const { return m_file_actions.size(); }
58351290Sdim
59351290Sdim  const FileAction *GetFileActionAtIndex(size_t idx) const;
60351290Sdim
61351290Sdim  const FileAction *GetFileActionForFD(int fd) const;
62351290Sdim
63351290Sdim  Flags &GetFlags() { return m_flags; }
64351290Sdim
65351290Sdim  const Flags &GetFlags() const { return m_flags; }
66351290Sdim
67351290Sdim  const FileSpec &GetWorkingDirectory() const;
68351290Sdim
69351290Sdim  void SetWorkingDirectory(const FileSpec &working_dir);
70351290Sdim
71351290Sdim  const char *GetProcessPluginName() const;
72351290Sdim
73351290Sdim  void SetProcessPluginName(llvm::StringRef plugin);
74351290Sdim
75351290Sdim  const FileSpec &GetShell() const;
76351290Sdim
77351290Sdim  void SetShell(const FileSpec &shell);
78351290Sdim
79351290Sdim  uint32_t GetResumeCount() const { return m_resume_count; }
80351290Sdim
81351290Sdim  void SetResumeCount(uint32_t c) { m_resume_count = c; }
82351290Sdim
83351290Sdim  bool GetLaunchInSeparateProcessGroup() const {
84351290Sdim    return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
85351290Sdim  }
86351290Sdim
87351290Sdim  void SetLaunchInSeparateProcessGroup(bool separate);
88351290Sdim
89351290Sdim  bool GetShellExpandArguments() const {
90351290Sdim    return m_flags.Test(lldb::eLaunchFlagShellExpandArguments);
91351290Sdim  }
92351290Sdim
93351290Sdim  void SetShellExpandArguments(bool expand);
94351290Sdim
95351290Sdim  void Clear();
96351290Sdim
97351290Sdim  bool ConvertArgumentsForLaunchingInShell(Status &error, bool localhost,
98351290Sdim                                           bool will_debug,
99351290Sdim                                           bool first_arg_is_full_shell_command,
100351290Sdim                                           int32_t num_resumes);
101351290Sdim
102351290Sdim  void
103351290Sdim  SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback,
104351290Sdim                            bool monitor_signals);
105351290Sdim
106351290Sdim  Host::MonitorChildProcessCallback GetMonitorProcessCallback() const {
107351290Sdim    return m_monitor_callback;
108351290Sdim  }
109351290Sdim
110351290Sdim  /// A Monitor callback which does not take any action on process events. Use
111351290Sdim  /// this if you don't need to take any particular action when the process
112351290Sdim  /// terminates, but you still need to reap it.
113351290Sdim  static bool NoOpMonitorCallback(lldb::pid_t pid, bool exited, int signal,
114351290Sdim                                  int status);
115351290Sdim
116351290Sdim  bool GetMonitorSignals() const { return m_monitor_signals; }
117351290Sdim
118351290Sdim  // If the LaunchInfo has a monitor callback, then arrange to monitor the
119351290Sdim  // process. Return true if the LaunchInfo has taken care of monitoring the
120351290Sdim  // process, and false if the caller might want to monitor the process
121351290Sdim  // themselves.
122351290Sdim
123351290Sdim  bool MonitorProcess() const;
124351290Sdim
125351290Sdim  PseudoTerminal &GetPTY() { return *m_pty; }
126351290Sdim
127351290Sdim  // Get and set the actual listener that will be used for the process events
128351290Sdim  lldb::ListenerSP GetListener() const { return m_listener_sp; }
129351290Sdim
130351290Sdim  void SetListener(const lldb::ListenerSP &listener_sp) {
131351290Sdim    m_listener_sp = listener_sp;
132351290Sdim  }
133351290Sdim
134351290Sdim  lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; }
135351290Sdim
136351290Sdim  void SetHijackListener(const lldb::ListenerSP &listener_sp) {
137351290Sdim    m_hijack_listener_sp = listener_sp;
138351290Sdim  }
139351290Sdim
140351290Sdim  void SetLaunchEventData(const char *data) { m_event_data.assign(data); }
141351290Sdim
142351290Sdim  const char *GetLaunchEventData() const { return m_event_data.c_str(); }
143351290Sdim
144351290Sdim  void SetDetachOnError(bool enable);
145351290Sdim
146351290Sdim  bool GetDetachOnError() const {
147351290Sdim    return m_flags.Test(lldb::eLaunchFlagDetachOnError);
148351290Sdim  }
149351290Sdim
150351290Sdimprotected:
151351290Sdim  FileSpec m_working_dir;
152351290Sdim  std::string m_plugin_name;
153351290Sdim  FileSpec m_shell;
154351290Sdim  Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
155351290Sdim  std::vector<FileAction> m_file_actions; // File actions for any other files
156351290Sdim  std::shared_ptr<PseudoTerminal> m_pty;
157351290Sdim  uint32_t m_resume_count; // How many times do we resume after launching
158351290Sdim  Host::MonitorChildProcessCallback m_monitor_callback;
159351290Sdim  void *m_monitor_callback_baton;
160351290Sdim  bool m_monitor_signals;
161351290Sdim  std::string m_event_data; // A string passed to the plugin launch, having no
162351290Sdim                            // meaning to the upper levels of lldb.
163351290Sdim  lldb::ListenerSP m_listener_sp;
164351290Sdim  lldb::ListenerSP m_hijack_listener_sp;
165351290Sdim};
166351290Sdim}
167351290Sdim
168351290Sdim#endif // liblldb_ProcessLaunch_Info_h
169