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