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