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