1 //===-- CommandOptionsProcessLaunch.cpp -----------------------------------===//
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 #include "CommandOptionsProcessLaunch.h"
10 
11 #include "lldb/Host/FileSystem.h"
12 #include "lldb/Host/HostInfo.h"
13 #include "lldb/Host/OptionParser.h"
14 #include "lldb/Interpreter/CommandCompletions.h"
15 #include "lldb/Interpreter/CommandObject.h"
16 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
17 #include "lldb/Interpreter/OptionArgParser.h"
18 #include "lldb/Target/ExecutionContext.h"
19 #include "lldb/Target/Platform.h"
20 #include "lldb/Target/Target.h"
21 
22 #include "llvm/ADT/ArrayRef.h"
23 
24 using namespace llvm;
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 #define LLDB_OPTIONS_process_launch
29 #include "CommandOptions.inc"
30 
31 Status CommandOptionsProcessLaunch::SetOptionValue(
32     uint32_t option_idx, llvm::StringRef option_arg,
33     ExecutionContext *execution_context) {
34   Status error;
35   const int short_option = g_process_launch_options[option_idx].short_option;
36 
37   switch (short_option) {
38   case 's': // Stop at program entry point
39     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
40     break;
41 
42   case 'i': // STDIN for read only
43   {
44     FileAction action;
45     if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
46       launch_info.AppendFileAction(action);
47     break;
48   }
49 
50   case 'o': // Open STDOUT for write only
51   {
52     FileAction action;
53     if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
54       launch_info.AppendFileAction(action);
55     break;
56   }
57 
58   case 'e': // STDERR for write only
59   {
60     FileAction action;
61     if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
62       launch_info.AppendFileAction(action);
63     break;
64   }
65 
66   case 'P': // Process plug-in name
67     launch_info.SetProcessPluginName(option_arg);
68     break;
69 
70   case 'n': // Disable STDIO
71   {
72     FileAction action;
73     const FileSpec dev_null(FileSystem::DEV_NULL);
74     if (action.Open(STDIN_FILENO, dev_null, true, false))
75       launch_info.AppendFileAction(action);
76     if (action.Open(STDOUT_FILENO, dev_null, false, true))
77       launch_info.AppendFileAction(action);
78     if (action.Open(STDERR_FILENO, dev_null, false, true))
79       launch_info.AppendFileAction(action);
80     break;
81   }
82 
83   case 'w':
84     launch_info.SetWorkingDirectory(FileSpec(option_arg));
85     break;
86 
87   case 't': // Open process in new terminal window
88     launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
89     break;
90 
91   case 'a': {
92     TargetSP target_sp =
93         execution_context ? execution_context->GetTargetSP() : TargetSP();
94     PlatformSP platform_sp =
95         target_sp ? target_sp->GetPlatform() : PlatformSP();
96     launch_info.GetArchitecture() =
97         Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
98   } break;
99 
100   case 'A': // Disable ASLR.
101   {
102     bool success;
103     const bool disable_aslr_arg =
104         OptionArgParser::ToBoolean(option_arg, true, &success);
105     if (success)
106       disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
107     else
108       error.SetErrorStringWithFormat(
109           "Invalid boolean value for disable-aslr option: '%s'",
110           option_arg.empty() ? "<null>" : option_arg.str().c_str());
111     break;
112   }
113 
114   case 'X': // shell expand args.
115   {
116     bool success;
117     const bool expand_args =
118         OptionArgParser::ToBoolean(option_arg, true, &success);
119     if (success)
120       launch_info.SetShellExpandArguments(expand_args);
121     else
122       error.SetErrorStringWithFormat(
123           "Invalid boolean value for shell-expand-args option: '%s'",
124           option_arg.empty() ? "<null>" : option_arg.str().c_str());
125     break;
126   }
127 
128   case 'c':
129     if (!option_arg.empty())
130       launch_info.SetShell(FileSpec(option_arg));
131     else
132       launch_info.SetShell(HostInfo::GetDefaultShell());
133     break;
134 
135   case 'E':
136     launch_info.GetEnvironment().insert(option_arg);
137     break;
138 
139   default:
140     error.SetErrorStringWithFormat("unrecognized short option character '%c'",
141                                    short_option);
142     break;
143   }
144   return error;
145 }
146 
147 llvm::ArrayRef<OptionDefinition> CommandOptionsProcessLaunch::GetDefinitions() {
148   return llvm::makeArrayRef(g_process_launch_options);
149 }
150