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
24namespace lldb_private {
25
26// ProcessLaunchInfo
27//
28// Describes any information that is required to launch a process.
29
30class ProcessLaunchInfo : public ProcessInfo {
31public:
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(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(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
85  }
86
87  void SetLaunchInSeparateProcessGroup(bool separate);
88
89  bool GetShellExpandArguments() const {
90    return m_flags.Test(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(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(lldb::eLaunchFlagDetachOnError);
131  }
132
133protected:
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