1 //===-- Driver.cpp ----------------------------------------------*- 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 #include "Driver.h"
11 
12 #include <getopt.h>
13 #include <libgen.h>
14 #include <sys/ioctl.h>
15 #include <termios.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <fcntl.h>
21 
22 #include <string>
23 
24 #include "IOChannel.h"
25 #include "lldb/API/SBCommandInterpreter.h"
26 #include "lldb/API/SBCommandReturnObject.h"
27 #include "lldb/API/SBCommunication.h"
28 #include "lldb/API/SBDebugger.h"
29 #include "lldb/API/SBEvent.h"
30 #include "lldb/API/SBHostOS.h"
31 #include "lldb/API/SBListener.h"
32 #include "lldb/API/SBStream.h"
33 #include "lldb/API/SBTarget.h"
34 #include "lldb/API/SBThread.h"
35 #include "lldb/API/SBProcess.h"
36 
37 using namespace lldb;
38 
39 static void reset_stdin_termios ();
40 static struct termios g_old_stdin_termios;
41 
42 static char *g_debugger_name =  (char *) "";
43 static Driver *g_driver = NULL;
44 
45 // In the Driver::MainLoop, we change the terminal settings.  This function is
46 // added as an atexit handler to make sure we clean them up.
47 static void
48 reset_stdin_termios ()
49 {
50     ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
51 }
52 
53 typedef struct
54 {
55     uint32_t usage_mask;                     // Used to mark options that can be used together.  If (1 << n & usage_mask) != 0
56                                              // then this option belongs to option set n.
57     bool required;                           // This option is required (in the current usage level)
58     const char * long_option;                // Full name for this option.
59     char short_option;                       // Single character for this option.
60     int option_has_arg;                      // no_argument, required_argument or optional_argument
61     uint32_t completion_type;                // Cookie the option class can use to do define the argument completion.
62     lldb::CommandArgumentType argument_type; // Type of argument this option takes
63     const char *  usage_text;                // Full text explaining what this options does and what (if any) argument to
64                                              // pass it.
65 } OptionDefinition;
66 
67 #define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
68 #define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
69 
70 static OptionDefinition g_options[] =
71 {
72     { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , NULL,  eArgTypeNone,
73         "Prints out the usage information for the LLDB debugger." },
74     { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , NULL,  eArgTypeNone,
75         "Prints out the current version number of the LLDB debugger." },
76     { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, NULL,  eArgTypeArchitecture,
77         "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must "
78         "be one of the architectures for which the program was compiled." },
79     { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, NULL,  eArgTypeFilename,
80         "Tells the debugger to use the file <filename> as the program to be debugged." },
81     { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, NULL,  eArgTypeProcessName,
82         "Tells the debugger to attach to a process with the given name." },
83     { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , NULL,  eArgTypeNone,
84         "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
85     { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, NULL,  eArgTypePid,
86         "Tells the debugger to attach to a process with the given pid." },
87     { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, NULL,  eArgTypeScriptLang,
88         "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  "
89         "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python "
90         "extensions have been implemented." },
91     { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , NULL,  eArgTypeNone,
92         "Tells the debugger to print out extra information for debugging itself." },
93     { LLDB_3_TO_5,       false, "source"         , 's', required_argument, NULL,  eArgTypeFilename,
94         "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
95     { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , NULL,  eArgTypeNone,
96         "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
97     { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , NULL,  eArgTypeNone,
98         "Do not automatically parse any '.lldbinit' files." },
99     { 0,                 false, NULL             , 0  , 0                , NULL,  eArgTypeNone,         NULL }
100 };
101 
102 static const uint32_t last_option_set_with_args = 2;
103 
104 Driver::Driver () :
105     SBBroadcaster ("Driver"),
106     m_debugger (SBDebugger::Create(false)),
107     m_editline_pty (),
108     m_editline_slave_fh (NULL),
109     m_editline_reader (),
110     m_io_channel_ap (),
111     m_option_data (),
112     m_waiting_for_command (false)
113 {
114     // We want to be able to handle CTRL+D in the terminal to have it terminate
115     // certain input
116     m_debugger.SetCloseInputOnEOF (false);
117     g_debugger_name = (char *) m_debugger.GetInstanceName();
118     if (g_debugger_name == NULL)
119         g_debugger_name = (char *) "";
120     g_driver = this;
121 }
122 
123 Driver::~Driver ()
124 {
125     g_driver = NULL;
126     g_debugger_name = NULL;
127 }
128 
129 void
130 Driver::CloseIOChannelFile ()
131 {
132     // Write and End of File sequence to the file descriptor to ensure any
133     // read functions can exit.
134     char eof_str[] = "\x04";
135     ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
136 
137     m_editline_pty.CloseMasterFileDescriptor();
138 
139     if (m_editline_slave_fh)
140     {
141         ::fclose (m_editline_slave_fh);
142         m_editline_slave_fh = NULL;
143     }
144 }
145 
146 // This function takes INDENT, which tells how many spaces to output at the front
147 // of each line; TEXT, which is the text that is to be output. It outputs the
148 // text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
149 // front of each line.  It breaks lines on spaces, tabs or newlines, shortening
150 // the line if necessary to not break in the middle of a word. It assumes that
151 // each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
152 
153 void
154 OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
155 {
156     int len = strlen (text);
157     std::string text_string (text);
158 
159     // Force indentation to be reasonable.
160     if (indent >= output_max_columns)
161         indent = 0;
162 
163     // Will it all fit on one line?
164 
165     if (len + indent < output_max_columns)
166         // Output as a single line
167         fprintf (out, "%*s%s\n", indent, "", text);
168     else
169     {
170         // We need to break it up into multiple lines.
171         int text_width = output_max_columns - indent - 1;
172         int start = 0;
173         int end = start;
174         int final_end = len;
175         int sub_len;
176 
177         while (end < final_end)
178         {
179               // Dont start the 'text' on a space, since we're already outputting the indentation.
180               while ((start < final_end) && (text[start] == ' '))
181                   start++;
182 
183               end = start + text_width;
184               if (end > final_end)
185                   end = final_end;
186               else
187               {
188                   // If we're not at the end of the text, make sure we break the line on white space.
189                   while (end > start
190                          && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
191                       end--;
192               }
193               sub_len = end - start;
194               std::string substring = text_string.substr (start, sub_len);
195               fprintf (out, "%*s%s\n", indent, "", substring.c_str());
196               start = end + 1;
197         }
198     }
199 }
200 
201 void
202 ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
203 {
204     uint32_t screen_width = 80;
205     uint32_t indent_level = 0;
206     const char *name = "lldb";
207 
208     fprintf (out, "\nUsage:\n\n");
209 
210     indent_level += 2;
211 
212 
213     // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
214     //                                                   <cmd> [options-for-level-1]
215     //                                                   etc.
216 
217     uint32_t num_options;
218     uint32_t num_option_sets = 0;
219 
220     for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
221     {
222         uint32_t this_usage_mask = option_table[num_options].usage_mask;
223         if (this_usage_mask == LLDB_OPT_SET_ALL)
224         {
225             if (num_option_sets == 0)
226                 num_option_sets = 1;
227         }
228         else
229         {
230             for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
231             {
232                 if (this_usage_mask & 1 << j)
233                 {
234                     if (num_option_sets <= j)
235                         num_option_sets = j + 1;
236                 }
237             }
238         }
239     }
240 
241     for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
242     {
243         uint32_t opt_set_mask;
244 
245         opt_set_mask = 1 << opt_set;
246 
247         if (opt_set > 0)
248             fprintf (out, "\n");
249         fprintf (out, "%*s%s", indent_level, "", name);
250         bool is_help_line = false;
251 
252         for (uint32_t i = 0; i < num_options; ++i)
253         {
254             if (option_table[i].usage_mask & opt_set_mask)
255             {
256                 CommandArgumentType arg_type = option_table[i].argument_type;
257                 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
258                 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
259                 // so we do it by hand here.
260                 if (option_table[i].short_option == 'h')
261                     is_help_line = true;
262 
263                 if (option_table[i].required)
264                 {
265                     if (option_table[i].option_has_arg == required_argument)
266                         fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
267                     else if (option_table[i].option_has_arg == optional_argument)
268                         fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
269                     else
270                         fprintf (out, " -%c", option_table[i].short_option);
271                 }
272                 else
273                 {
274                     if (option_table[i].option_has_arg == required_argument)
275                         fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
276                     else if (option_table[i].option_has_arg == optional_argument)
277                         fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
278                     else
279                         fprintf (out, " [-%c]", option_table[i].short_option);
280                 }
281             }
282         }
283         if (!is_help_line && (opt_set <= last_option_set_with_args))
284             fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
285     }
286 
287     fprintf (out, "\n\n");
288 
289     // Now print out all the detailed information about the various options:  long form, short form and help text:
290     //   -- long_name <argument>
291     //   - short <argument>
292     //   help text
293 
294     // This variable is used to keep track of which options' info we've printed out, because some options can be in
295     // more than one usage level, but we only want to print the long form of its information once.
296 
297     Driver::OptionData::OptionSet options_seen;
298     Driver::OptionData::OptionSet::iterator pos;
299 
300     indent_level += 5;
301 
302     for (uint32_t i = 0; i < num_options; ++i)
303     {
304         // Only print this option if we haven't already seen it.
305         pos = options_seen.find (option_table[i].short_option);
306         if (pos == options_seen.end())
307         {
308             CommandArgumentType arg_type = option_table[i].argument_type;
309             const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
310 
311             options_seen.insert (option_table[i].short_option);
312             fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
313             if (arg_type != eArgTypeNone)
314                 fprintf (out, "<%s>", arg_name);
315             fprintf (out, "\n");
316             fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
317             if (arg_type != eArgTypeNone)
318                 fprintf (out, "<%s>", arg_name);
319             fprintf (out, "\n");
320             indent_level += 5;
321             OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
322             indent_level -= 5;
323             fprintf (out, "\n");
324         }
325     }
326 
327     indent_level -= 5;
328 
329     fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
330                   "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
331                   "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
332              indent_level, "",
333              indent_level, "",
334              name,
335              indent_level, "");
336 }
337 
338 void
339 BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
340                   uint32_t num_options)
341 {
342     if (num_options == 0)
343         return;
344 
345     uint32_t i;
346     uint32_t j;
347     std::bitset<256> option_seen;
348 
349     getopt_table.resize (num_options + 1);
350 
351     for (i = 0, j = 0; i < num_options; ++i)
352     {
353         char short_opt = expanded_option_table[i].short_option;
354 
355         if (option_seen.test(short_opt) == false)
356         {
357             getopt_table[j].name    = expanded_option_table[i].long_option;
358             getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
359             getopt_table[j].flag    = NULL;
360             getopt_table[j].val     = expanded_option_table[i].short_option;
361             option_seen.set(short_opt);
362             ++j;
363         }
364     }
365 
366     getopt_table[j].name    = NULL;
367     getopt_table[j].has_arg = 0;
368     getopt_table[j].flag    = NULL;
369     getopt_table[j].val     = 0;
370 
371 }
372 
373 Driver::OptionData::OptionData () :
374     m_args(),
375     m_script_lang (lldb::eScriptLanguageDefault),
376     m_crash_log (),
377     m_source_command_files (),
378     m_debug_mode (false),
379     m_print_version (false),
380     m_print_help (false),
381     m_use_external_editor(false),
382     m_wait_for(false),
383     m_process_name(),
384     m_process_pid(LLDB_INVALID_PROCESS_ID),
385     m_seen_options()
386 {
387 }
388 
389 Driver::OptionData::~OptionData ()
390 {
391 }
392 
393 void
394 Driver::OptionData::Clear ()
395 {
396     m_args.clear ();
397     m_script_lang = lldb::eScriptLanguageDefault;
398     m_source_command_files.clear ();
399     m_debug_mode = false;
400     m_print_help = false;
401     m_print_version = false;
402     m_use_external_editor = false;
403     m_wait_for = false;
404     m_process_name.erase();
405     m_process_pid = LLDB_INVALID_PROCESS_ID;
406 }
407 
408 void
409 Driver::ResetOptionValues ()
410 {
411     m_option_data.Clear ();
412 }
413 
414 const char *
415 Driver::GetFilename() const
416 {
417     if (m_option_data.m_args.empty())
418         return NULL;
419     return m_option_data.m_args.front().c_str();
420 }
421 
422 const char *
423 Driver::GetCrashLogFilename() const
424 {
425     if (m_option_data.m_crash_log.empty())
426         return NULL;
427     return m_option_data.m_crash_log.c_str();
428 }
429 
430 lldb::ScriptLanguage
431 Driver::GetScriptLanguage() const
432 {
433     return m_option_data.m_script_lang;
434 }
435 
436 size_t
437 Driver::GetNumSourceCommandFiles () const
438 {
439     return m_option_data.m_source_command_files.size();
440 }
441 
442 const char *
443 Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
444 {
445     if (idx < m_option_data.m_source_command_files.size())
446         return m_option_data.m_source_command_files[idx].c_str();
447     return NULL;
448 }
449 
450 bool
451 Driver::GetDebugMode() const
452 {
453     return m_option_data.m_debug_mode;
454 }
455 
456 
457 // Check the arguments that were passed to this program to make sure they are valid and to get their
458 // argument values (if any).  Return a boolean value indicating whether or not to start up the full
459 // debugger (i.e. the Command Interpreter) or not.  Return FALSE if the arguments were invalid OR
460 // if the user only wanted help or version information.
461 
462 SBError
463 Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
464 {
465     ResetOptionValues ();
466 
467     SBCommandReturnObject result;
468 
469     SBError error;
470     std::string option_string;
471     struct option *long_options = NULL;
472     std::vector<struct option> long_options_vector;
473     uint32_t num_options;
474 
475     for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
476         /* Do Nothing. */;
477 
478     if (num_options == 0)
479     {
480         if (argc > 1)
481             error.SetErrorStringWithFormat ("invalid number of options");
482         return error;
483     }
484 
485     BuildGetOptTable (g_options, long_options_vector, num_options);
486 
487     if (long_options_vector.empty())
488         long_options = NULL;
489     else
490         long_options = &long_options_vector.front();
491 
492     if (long_options == NULL)
493     {
494         error.SetErrorStringWithFormat ("invalid long options");
495         return error;
496     }
497 
498     // Build the option_string argument for call to getopt_long.
499 
500     for (int i = 0; long_options[i].name != NULL; ++i)
501     {
502         if (long_options[i].flag == NULL)
503         {
504             option_string.push_back ((char) long_options[i].val);
505             switch (long_options[i].has_arg)
506             {
507                 default:
508                 case no_argument:
509                     break;
510                 case required_argument:
511                     option_string.push_back (':');
512                     break;
513                 case optional_argument:
514                     option_string.append ("::");
515                     break;
516             }
517         }
518     }
519 
520     // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
521     // know at that point whether we should read in init files yet.  So we don't read them in in the
522     // Driver constructor, then set the flags back to "read them in" here, and then if we see the
523     // "-n" flag, we'll turn it off again.  Finally we have to read them in by hand later in the
524     // main loop.
525 
526     m_debugger.SkipLLDBInitFiles (false);
527     m_debugger.SkipAppInitFiles (false);
528 
529     // Prepare for & make calls to getopt_long.
530 #if __GLIBC__
531     optind = 0;
532 #else
533     optreset = 1;
534     optind = 1;
535 #endif
536     int val;
537     while (1)
538     {
539         int long_options_index = -1;
540         val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
541 
542         if (val == -1)
543             break;
544         else if (val == '?')
545         {
546             m_option_data.m_print_help = true;
547             error.SetErrorStringWithFormat ("unknown or ambiguous option");
548             break;
549         }
550         else if (val == 0)
551             continue;
552         else
553         {
554             m_option_data.m_seen_options.insert ((char) val);
555             if (long_options_index == -1)
556             {
557                 for (int i = 0;
558                      long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
559                      ++i)
560                 {
561                     if (long_options[i].val == val)
562                     {
563                         long_options_index = i;
564                         break;
565                     }
566                 }
567             }
568 
569             if (long_options_index >= 0)
570             {
571                 const char short_option = (char) g_options[long_options_index].short_option;
572 
573                 switch (short_option)
574                 {
575                     case 'h':
576                         m_option_data.m_print_help = true;
577                         break;
578 
579                     case 'v':
580                         m_option_data.m_print_version = true;
581                         break;
582 
583                     case 'c':
584                         m_option_data.m_crash_log = optarg;
585                         break;
586 
587                     case 'e':
588                         m_option_data.m_use_external_editor = true;
589                         break;
590 
591                     case 'x':
592                         m_debugger.SkipLLDBInitFiles (true);
593                         m_debugger.SkipAppInitFiles (true);
594                         break;
595 
596                     case 'f':
597                         {
598                             SBFileSpec file(optarg);
599                             if (file.Exists())
600                             {
601                                 m_option_data.m_args.push_back (optarg);
602                             }
603                             else if (file.ResolveExecutableLocation())
604                             {
605                                 char path[PATH_MAX];
606                                 file.GetPath (path, sizeof(path));
607                                 m_option_data.m_args.push_back (path);
608                             }
609                             else
610                                 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
611                         }
612                         break;
613 
614                     case 'a':
615                         if (!m_debugger.SetDefaultArchitecture (optarg))
616                             error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
617                         break;
618 
619                     case 'l':
620                         m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
621                         break;
622 
623                     case 'd':
624                         m_option_data.m_debug_mode = true;
625                         break;
626 
627                     case 'n':
628                         m_option_data.m_process_name = optarg;
629                         break;
630 
631                     case 'w':
632                         m_option_data.m_wait_for = true;
633                         break;
634 
635                     case 'p':
636                         {
637                             char *remainder;
638                             m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
639                             if (remainder == optarg || *remainder != '\0')
640                                 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
641                                                                 optarg);
642                         }
643                         break;
644                     case 's':
645                         {
646                             SBFileSpec file(optarg);
647                             if (file.Exists())
648                                 m_option_data.m_source_command_files.push_back (optarg);
649                             else if (file.ResolveExecutableLocation())
650                             {
651                                 char final_path[PATH_MAX];
652                                 file.GetPath (final_path, sizeof(final_path));
653                                 std::string path_str (final_path);
654                                 m_option_data.m_source_command_files.push_back (path_str);
655                             }
656                             else
657                                 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
658                         }
659                         break;
660 
661                     default:
662                         m_option_data.m_print_help = true;
663                         error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
664                         break;
665                 }
666             }
667             else
668             {
669                 error.SetErrorStringWithFormat ("invalid option with value %i", val);
670             }
671             if (error.Fail())
672             {
673                 return error;
674             }
675         }
676     }
677 
678     if (error.Fail() || m_option_data.m_print_help)
679     {
680         ShowUsage (out_fh, g_options, m_option_data);
681         exit = true;
682     }
683     else if (m_option_data.m_print_version)
684     {
685         ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
686         exit = true;
687     }
688     else if (! m_option_data.m_crash_log.empty())
689     {
690         // Handle crash log stuff here.
691     }
692     else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
693     {
694         // Any arguments that are left over after option parsing are for
695         // the program. If a file was specified with -f then the filename
696         // is already in the m_option_data.m_args array, and any remaining args
697         // are arguments for the inferior program. If no file was specified with
698         // -f, then what is left is the program name followed by any arguments.
699 
700         // Skip any options we consumed with getopt_long
701         argc -= optind;
702         argv += optind;
703 
704         if (argc > 0)
705         {
706             for (int arg_idx=0; arg_idx<argc; ++arg_idx)
707             {
708                 const char *arg = argv[arg_idx];
709                 if (arg)
710                     m_option_data.m_args.push_back (arg);
711             }
712         }
713 
714     }
715     else
716     {
717         // Skip any options we consumed with getopt_long
718         argc -= optind;
719         argv += optind;
720 
721         if (argc > 0)
722             ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
723     }
724 
725     return error;
726 }
727 
728 size_t
729 Driver::GetProcessSTDOUT ()
730 {
731     //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
732     char stdio_buffer[1024];
733     size_t len;
734     size_t total_bytes = 0;
735     while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
736     {
737         m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
738         total_bytes += len;
739     }
740     return total_bytes;
741 }
742 
743 size_t
744 Driver::GetProcessSTDERR ()
745 {
746     //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
747     char stdio_buffer[1024];
748     size_t len;
749     size_t total_bytes = 0;
750     while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
751     {
752         m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
753         total_bytes += len;
754     }
755     return total_bytes;
756 }
757 
758 void
759 Driver::UpdateSelectedThread ()
760 {
761     using namespace lldb;
762     SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
763     if (process.IsValid())
764     {
765         SBThread curr_thread (process.GetSelectedThread());
766         SBThread thread;
767         StopReason curr_thread_stop_reason = eStopReasonInvalid;
768         curr_thread_stop_reason = curr_thread.GetStopReason();
769 
770         if (!curr_thread.IsValid() ||
771             curr_thread_stop_reason == eStopReasonInvalid ||
772             curr_thread_stop_reason == eStopReasonNone)
773         {
774             // Prefer a thread that has just completed its plan over another thread as current thread.
775             SBThread plan_thread;
776             SBThread other_thread;
777             const size_t num_threads = process.GetNumThreads();
778             size_t i;
779             for (i = 0; i < num_threads; ++i)
780             {
781                 thread = process.GetThreadAtIndex(i);
782                 StopReason thread_stop_reason = thread.GetStopReason();
783                 switch (thread_stop_reason)
784                 {
785                 default:
786                 case eStopReasonInvalid:
787                 case eStopReasonNone:
788                     break;
789 
790                 case eStopReasonTrace:
791                 case eStopReasonBreakpoint:
792                 case eStopReasonWatchpoint:
793                 case eStopReasonSignal:
794                 case eStopReasonException:
795                     if (!other_thread.IsValid())
796                         other_thread = thread;
797                     break;
798                 case eStopReasonPlanComplete:
799                     if (!plan_thread.IsValid())
800                         plan_thread = thread;
801                     break;
802                 }
803             }
804             if (plan_thread.IsValid())
805                 process.SetSelectedThread (plan_thread);
806             else if (other_thread.IsValid())
807                 process.SetSelectedThread (other_thread);
808             else
809             {
810                 if (curr_thread.IsValid())
811                     thread = curr_thread;
812                 else
813                     thread = process.GetThreadAtIndex(0);
814 
815                 if (thread.IsValid())
816                     process.SetSelectedThread (thread);
817             }
818         }
819     }
820 }
821 
822 
823 // This function handles events that were broadcast by the process.
824 void
825 Driver::HandleProcessEvent (const SBEvent &event)
826 {
827     using namespace lldb;
828     const uint32_t event_type = event.GetType();
829 
830     if (event_type & SBProcess::eBroadcastBitSTDOUT)
831     {
832         // The process has stdout available, get it and write it out to the
833         // appropriate place.
834         GetProcessSTDOUT ();
835     }
836     else if (event_type & SBProcess::eBroadcastBitSTDERR)
837     {
838         // The process has stderr available, get it and write it out to the
839         // appropriate place.
840         GetProcessSTDERR ();
841     }
842     else if (event_type & SBProcess::eBroadcastBitStateChanged)
843     {
844         // Drain all stout and stderr so we don't see any output come after
845         // we print our prompts
846         GetProcessSTDOUT ();
847         GetProcessSTDERR ();
848         // Something changed in the process;  get the event and report the process's current status and location to
849         // the user.
850         StateType event_state = SBProcess::GetStateFromEvent (event);
851         if (event_state == eStateInvalid)
852             return;
853 
854         SBProcess process (SBProcess::GetProcessFromEvent (event));
855         assert (process.IsValid());
856 
857         switch (event_state)
858         {
859         case eStateInvalid:
860         case eStateUnloaded:
861         case eStateConnected:
862         case eStateAttaching:
863         case eStateLaunching:
864         case eStateStepping:
865         case eStateDetached:
866             {
867                 char message[1024];
868                 int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(),
869                                               m_debugger.StateAsCString (event_state));
870                 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
871             }
872             break;
873 
874         case eStateRunning:
875             // Don't be chatty when we run...
876             break;
877 
878         case eStateExited:
879             {
880                 SBCommandReturnObject result;
881                 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
882                 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
883                 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
884             }
885             break;
886 
887         case eStateStopped:
888         case eStateCrashed:
889         case eStateSuspended:
890             // Make sure the program hasn't been auto-restarted:
891             if (SBProcess::GetRestartedFromEvent (event))
892             {
893                 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
894                 char message[1024];
895                 int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n",
896                                               process.GetProcessID());
897                 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
898             }
899             else
900             {
901                 SBCommandReturnObject result;
902                 UpdateSelectedThread ();
903                 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
904                 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
905                 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
906             }
907             break;
908         }
909     }
910 }
911 
912 //  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
913 
914 bool
915 Driver::HandleIOEvent (const SBEvent &event)
916 {
917     bool quit = false;
918 
919     const uint32_t event_type = event.GetType();
920 
921     if (event_type & IOChannel::eBroadcastBitHasUserInput)
922     {
923         // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
924         // handling.
925 
926         const char *command_string = SBEvent::GetCStringFromEvent(event);
927         if (command_string == NULL)
928             command_string = "";
929         SBCommandReturnObject result;
930 
931         // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
932         // output orderings and problems with the prompt.
933         m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
934 
935         if (result.GetOutputSize() > 0)
936             m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC);
937 
938         if (result.GetErrorSize() > 0)
939             m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC);
940 
941         // We are done getting and running our command, we can now clear the
942         // m_waiting_for_command so we can get another one.
943         m_waiting_for_command = false;
944 
945         // If our editline input reader is active, it means another input reader
946         // got pushed onto the input reader and caused us to become deactivated.
947         // When the input reader above us gets popped, we will get re-activated
948         // and our prompt will refresh in our callback
949         if (m_editline_reader.IsActive())
950         {
951             ReadyForCommand ();
952         }
953     }
954     else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
955     {
956         // This is here to handle control-c interrupts from the user.  It has not yet really been implemented.
957         // TO BE DONE:  PROPERLY HANDLE CONTROL-C FROM USER
958         //m_io_channel_ap->CancelInput();
959         // Anything else?  Send Interrupt to process?
960     }
961     else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
962              (event_type & IOChannel::eBroadcastBitThreadDidExit))
963     {
964         // If the IOChannel thread is trying to go away, then it is definitely
965         // time to end the debugging session.
966         quit = true;
967     }
968 
969     return quit;
970 }
971 
972 void
973 Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
974 {
975     Driver *driver = (Driver*)baton;
976     driver->GetFromMaster ((const char *)src, src_len);
977 }
978 
979 void
980 Driver::GetFromMaster (const char *src, size_t src_len)
981 {
982     // Echo the characters back to the Debugger's stdout, that way if you
983     // type characters while a command is running, you'll see what you've typed.
984     FILE *out_fh = m_debugger.GetOutputFileHandle();
985     if (out_fh)
986         ::fwrite (src, 1, src_len, out_fh);
987 }
988 
989 size_t
990 Driver::EditLineInputReaderCallback
991 (
992     void *baton,
993     SBInputReader *reader,
994     InputReaderAction notification,
995     const char *bytes,
996     size_t bytes_len
997 )
998 {
999     Driver *driver = (Driver *)baton;
1000 
1001     switch (notification)
1002     {
1003     case eInputReaderActivate:
1004         break;
1005 
1006     case eInputReaderReactivate:
1007         driver->ReadyForCommand();
1008         break;
1009 
1010     case eInputReaderDeactivate:
1011         break;
1012 
1013     case eInputReaderAsynchronousOutputWritten:
1014         if (driver->m_io_channel_ap.get() != NULL)
1015             driver->m_io_channel_ap->RefreshPrompt();
1016         break;
1017 
1018     case eInputReaderInterrupt:
1019         if (driver->m_io_channel_ap.get() != NULL)
1020         {
1021             driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
1022             driver->m_io_channel_ap->RefreshPrompt();
1023         }
1024         break;
1025 
1026     case eInputReaderEndOfFile:
1027         if (driver->m_io_channel_ap.get() != NULL)
1028         {
1029             driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
1030             driver->m_io_channel_ap->RefreshPrompt ();
1031         }
1032         write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
1033         break;
1034 
1035     case eInputReaderGotToken:
1036         write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
1037         break;
1038 
1039     case eInputReaderDone:
1040         break;
1041     }
1042     return bytes_len;
1043 }
1044 
1045 void
1046 Driver::MainLoop ()
1047 {
1048     char error_str[1024];
1049     if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
1050     {
1051         ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1052         exit(1);
1053     }
1054     else
1055     {
1056         const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1057         if (driver_slave_name == NULL)
1058         {
1059             ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1060             exit(2);
1061         }
1062         else
1063         {
1064             m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1065             if (m_editline_slave_fh == NULL)
1066             {
1067                 SBError error;
1068                 error.SetErrorToErrno();
1069                 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1070                            error.GetCString());
1071                 exit(3);
1072             }
1073 
1074             ::setbuf (m_editline_slave_fh, NULL);
1075         }
1076     }
1077 
1078     lldb_utility::PseudoTerminal editline_output_pty;
1079     FILE *editline_output_slave_fh = NULL;
1080 
1081     if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1082     {
1083         ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1084         exit(1);
1085     }
1086     else
1087     {
1088         const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1089         if (output_slave_name == NULL)
1090         {
1091             ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1092             exit(2);
1093         }
1094         else
1095         {
1096             editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1097             if (editline_output_slave_fh == NULL)
1098             {
1099                 SBError error;
1100                 error.SetErrorToErrno();
1101                 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1102                            error.GetCString());
1103                 exit(3);
1104             }
1105             ::setbuf (editline_output_slave_fh, NULL);
1106         }
1107     }
1108 
1109    // struct termios stdin_termios;
1110 
1111     if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
1112         atexit (reset_stdin_termios);
1113 
1114     ::setbuf (stdin, NULL);
1115     ::setbuf (stdout, NULL);
1116 
1117     m_debugger.SetErrorFileHandle (stderr, false);
1118     m_debugger.SetOutputFileHandle (stdout, false);
1119     m_debugger.SetInputFileHandle (stdin, true);
1120 
1121     m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
1122 
1123     // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
1124     // for that purpose.  The reason you need to do this is a curious reason...  editline will echo
1125     // characters to the PTY when it gets characters while el_gets is not running, and then when
1126     // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1127     // if there are unconsumed characters in the out buffer.
1128     // However, you don't need to do anything with the characters, since editline will dump these
1129     // unconsumed characters after printing the prompt again in el_gets.
1130 
1131     SBCommunication master_out_comm("driver.editline");
1132     master_out_comm.SetCloseOnEOF (false);
1133     master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1134     master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1135 
1136     if (master_out_comm.ReadThreadStart () == false)
1137     {
1138         ::fprintf (stderr, "error: failed to start master out read thread");
1139         exit(5);
1140     }
1141 
1142     SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
1143 
1144     m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1145 
1146     SBCommunication out_comm_2("driver.editline_output");
1147     out_comm_2.SetCloseOnEOF (false);
1148     out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1149     out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1150 
1151     if (out_comm_2.ReadThreadStart () == false)
1152     {
1153         ::fprintf (stderr, "error: failed to start libedit output read thread");
1154         exit (5);
1155     }
1156 
1157 
1158     struct winsize window_size;
1159     if (isatty (STDIN_FILENO)
1160         && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1161     {
1162         if (window_size.ws_col > 0)
1163             m_debugger.SetTerminalWidth (window_size.ws_col);
1164     }
1165 
1166     // Since input can be redirected by the debugger, we must insert our editline
1167     // input reader in the queue so we know when our reader should be active
1168     // and so we can receive bytes only when we are supposed to.
1169     SBError err (m_editline_reader.Initialize (m_debugger,
1170                                                Driver::EditLineInputReaderCallback, // callback
1171                                                this,                              // baton
1172                                                eInputReaderGranularityByte,       // token_size
1173                                                NULL,                              // end token - NULL means never done
1174                                                NULL,                              // prompt - taken care of elsewhere
1175                                                false));                           // echo input - don't need Debugger
1176                                                                                   // to do this, we handle it elsewhere
1177 
1178     if (err.Fail())
1179     {
1180         ::fprintf (stderr, "error: %s", err.GetCString());
1181         exit (6);
1182     }
1183 
1184     m_debugger.PushInputReader (m_editline_reader);
1185 
1186     SBListener listener(m_debugger.GetListener());
1187     if (listener.IsValid())
1188     {
1189 
1190         listener.StartListeningForEvents (*m_io_channel_ap,
1191                                           IOChannel::eBroadcastBitHasUserInput |
1192                                           IOChannel::eBroadcastBitUserInterrupt |
1193                                           IOChannel::eBroadcastBitThreadShouldExit |
1194                                           IOChannel::eBroadcastBitThreadDidStart |
1195                                           IOChannel::eBroadcastBitThreadDidExit);
1196 
1197         if (m_io_channel_ap->Start ())
1198         {
1199             bool iochannel_thread_exited = false;
1200 
1201             listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
1202                                               SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1203                                               SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1204                                               SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
1205 
1206             // Before we handle any options from the command line, we parse the
1207             // .lldbinit file in the user's home directory.
1208             SBCommandReturnObject result;
1209             sb_interpreter.SourceInitFileInHomeDirectory(result);
1210             if (GetDebugMode())
1211             {
1212                 result.PutError (m_debugger.GetErrorFileHandle());
1213                 result.PutOutput (m_debugger.GetOutputFileHandle());
1214             }
1215 
1216             // Now we handle options we got from the command line
1217             char command_string[PATH_MAX * 2];
1218             const size_t num_source_command_files = GetNumSourceCommandFiles();
1219             if (num_source_command_files > 0)
1220             {
1221                 for (size_t i=0; i < num_source_command_files; ++i)
1222                 {
1223                     const char *command_file = GetSourceCommandFileAtIndex(i);
1224                     ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
1225                     m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
1226                     if (GetDebugMode())
1227                     {
1228                         result.PutError (m_debugger.GetErrorFileHandle());
1229                         result.PutOutput (m_debugger.GetOutputFileHandle());
1230                     }
1231                 }
1232             }
1233 
1234             const size_t num_args = m_option_data.m_args.size();
1235             if (num_args > 0)
1236             {
1237                 char arch_name[64];
1238                 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
1239                     ::snprintf (command_string,
1240                                 sizeof (command_string),
1241                                 "target create --arch=%s '%s'",
1242                                 arch_name,
1243                                 m_option_data.m_args[0].c_str());
1244                 else
1245                     ::snprintf (command_string,
1246                                 sizeof(command_string),
1247                                 "target create '%s'",
1248                                 m_option_data.m_args[0].c_str());
1249 
1250                 m_debugger.HandleCommand (command_string);
1251 
1252                 if (num_args > 1)
1253                 {
1254                     m_debugger.HandleCommand ("settings clear target.process.run-args");
1255                     char arg_cstr[1024];
1256                     for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1257                     {
1258                         ::snprintf (arg_cstr,
1259                                     sizeof(arg_cstr),
1260                                     "settings append target.process.run-args \"%s\"",
1261                                     m_option_data.m_args[arg_idx].c_str());
1262                         m_debugger.HandleCommand (arg_cstr);
1263                     }
1264                 }
1265             }
1266 
1267             // Now that all option parsing is done, we try and parse the .lldbinit
1268             // file in the current working directory
1269             sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1270             if (GetDebugMode())
1271             {
1272                 result.PutError(m_debugger.GetErrorFileHandle());
1273                 result.PutOutput(m_debugger.GetOutputFileHandle());
1274             }
1275 
1276             SBEvent event;
1277 
1278             // Make sure the IO channel is started up before we try to tell it we
1279             // are ready for input
1280             listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1281                                                          *m_io_channel_ap,
1282                                                          IOChannel::eBroadcastBitThreadDidStart,
1283                                                          event);
1284             // If we were asked to attach, then do that here:
1285             // I'm going to use the command string rather than directly
1286             // calling the API's because then I don't have to recode the
1287             // event handling here.
1288             if (!m_option_data.m_process_name.empty()
1289                 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1290             {
1291                 std::string command_str("process attach ");
1292                 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1293                 {
1294                     command_str.append("-p ");
1295                     char pid_buffer[32];
1296                     ::snprintf (pid_buffer, sizeof(pid_buffer), "%d", m_option_data.m_process_pid);
1297                     command_str.append(pid_buffer);
1298                 }
1299                 else
1300                 {
1301                     command_str.append("-n \"");
1302                     command_str.append(m_option_data.m_process_name);
1303                     command_str.push_back('\"');
1304                     if (m_option_data.m_wait_for)
1305                         command_str.append(" -w");
1306                 }
1307 
1308                 if (m_debugger.GetOutputFileHandle())
1309                     ::fprintf (m_debugger.GetOutputFileHandle(),
1310                                "Attaching to process with:\n    %s\n",
1311                                command_str.c_str());
1312 
1313                 // Force the attach to be synchronous:
1314                 bool orig_async = m_debugger.GetAsync();
1315                 m_debugger.SetAsync(true);
1316                 m_debugger.HandleCommand(command_str.c_str());
1317                 m_debugger.SetAsync(orig_async);
1318             }
1319 
1320             ReadyForCommand ();
1321 
1322             bool done = false;
1323             while (!done)
1324             {
1325                 listener.WaitForEvent (UINT32_MAX, event);
1326                 if (event.IsValid())
1327                 {
1328                     if (event.GetBroadcaster().IsValid())
1329                     {
1330                         uint32_t event_type = event.GetType();
1331                         if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1332                         {
1333                             if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1334                                 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1335                             {
1336                                 done = true;
1337                                 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1338                                     iochannel_thread_exited = true;
1339                             }
1340                             else
1341                                 done = HandleIOEvent (event);
1342                         }
1343                         else if (event.BroadcasterMatchesRef (m_debugger.GetSelectedTarget().GetProcess().GetBroadcaster()))
1344                         {
1345                             HandleProcessEvent (event);
1346                         }
1347                         else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1348                         {
1349                             if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1350                                 done = true;
1351                             else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1352                             {
1353                                 const char *data = SBEvent::GetCStringFromEvent (event);
1354                                 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1355                             }
1356                             else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1357                             {
1358                                 const char *data = SBEvent::GetCStringFromEvent (event);
1359                                 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1360                             }
1361                         }
1362                     }
1363                 }
1364             }
1365 
1366             reset_stdin_termios ();
1367 
1368             CloseIOChannelFile ();
1369 
1370             if (!iochannel_thread_exited)
1371             {
1372                 event.Clear();
1373                 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1374                                                              IOChannel::eBroadcastBitThreadDidExit,
1375                                                              event);
1376                 if (!event.IsValid())
1377                 {
1378                     // Send end EOF to the driver file descriptor
1379                     m_io_channel_ap->Stop();
1380                 }
1381             }
1382 
1383             SBDebugger::Destroy (m_debugger);
1384         }
1385     }
1386 }
1387 
1388 
1389 void
1390 Driver::ReadyForCommand ()
1391 {
1392     if (m_waiting_for_command == false)
1393     {
1394         m_waiting_for_command = true;
1395         BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1396     }
1397 }
1398 
1399 
1400 void
1401 sigwinch_handler (int signo)
1402 {
1403     struct winsize window_size;
1404     if (isatty (STDIN_FILENO)
1405         && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1406     {
1407         if ((window_size.ws_col > 0) && (strlen (g_debugger_name) > 0))
1408         {
1409             char width_str_buffer[25];
1410             ::sprintf (width_str_buffer, "%d", window_size.ws_col);
1411             SBDebugger::SetInternalVariable ("term-width", width_str_buffer, g_debugger_name);
1412         }
1413     }
1414 }
1415 
1416 void
1417 sigint_handler (int signo)
1418 {
1419 	static bool g_interrupt_sent = false;
1420     if (g_driver)
1421 	{
1422 		if (!g_interrupt_sent)
1423 		{
1424 			g_interrupt_sent = true;
1425         	g_driver->GetDebugger().DispatchInputInterrupt();
1426 			g_interrupt_sent = false;
1427 			return;
1428 		}
1429 	}
1430 
1431 	exit (signo);
1432 }
1433 
1434 int
1435 main (int argc, char const *argv[], const char *envp[])
1436 {
1437     SBDebugger::Initialize();
1438 
1439     SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
1440 
1441     signal (SIGPIPE, SIG_IGN);
1442     signal (SIGWINCH, sigwinch_handler);
1443     signal (SIGINT, sigint_handler);
1444 
1445     // Create a scope for driver so that the driver object will destroy itself
1446     // before SBDebugger::Terminate() is called.
1447     {
1448         Driver driver;
1449 
1450         bool exit = false;
1451         SBError error (driver.ParseArgs (argc, argv, stdout, exit));
1452         if (error.Fail())
1453         {
1454             const char *error_cstr = error.GetCString ();
1455             if (error_cstr)
1456                 ::fprintf (stderr, "error: %s\n", error_cstr);
1457         }
1458         else if (!exit)
1459         {
1460             driver.MainLoop ();
1461         }
1462     }
1463 
1464     SBDebugger::Terminate();
1465     return 0;
1466 }
1467