Added a new variant of SBTarget::Launch() that deprectates the old one that
takes separate file handles for stdin, stdout, and stder and also allows for
the working directory to be specified.

Added support to "process launch" to a new option: --working-dir=PATH. We
can now set the working directory. If this is not set, it defaults to that
of the process that has LLDB loaded. Added the working directory to the
host LaunchInNewTerminal function to allows the current working directory 
to be set in processes that are spawned in their own terminal. Also hooked this
up to the lldb_private::Process and all mac plug-ins. The linux plug-in had its
API changed, but nothing is making use of it yet. Modfied "debugserver" and
"darwin-debug" to also handle the current working directory options and modified
the code in LLDB that spawns these tools to pass the info along.

Fixed ProcessGDBRemote to properly pass along all file handles for stdin, stdout
and stderr. 

After clearing the default values for the stdin/out/err file handles for
process to be NULL, we had a crasher in UserSettingsController::UpdateStringVariable
which is now fixed. Also fixed the setting of boolean values to be able to
be set as "true", "yes", "on", "1" for true (case insensitive) and "false", "no",
"off", or "0" for false.

Fixed debugserver to properly handle files for STDIN, STDOUT and STDERR that are not
already opened. Previous to this fix debugserver would only correctly open and dupe
file handles for the slave side of a pseudo terminal. It now correctly handles
getting STDIN for the inferior from a file, and spitting STDOUT and STDERR out to
files. Also made sure the file handles were correctly opened with the NOCTTY flag
for terminals.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@124060 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index fe4e068..ffec00e 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -375,7 +375,8 @@
     uint32_t launch_flags,
     const char *stdin_path,
     const char *stdout_path,
-    const char *stderr_path
+    const char *stderr_path,
+    const char *working_dir
 )
 {
     Error error;
@@ -400,7 +401,10 @@
             error = StartDebugserverProcess (host_port,
                                              argv,
                                              envp,
-                                             NULL, //stdin_path,
+                                             stdin_path,
+                                             stdout_path,
+                                             stderr_path,
+                                             working_dir,
                                              launch_process,
                                              LLDB_INVALID_PROCESS_ID,
                                              NULL, false,
@@ -420,10 +424,14 @@
             error = StartDebugserverProcess (host_port,
                                              NULL,
                                              NULL,
-                                             NULL, //stdin_path
+                                             stdin_path,
+                                             stdout_path,
+                                             stderr_path,
+                                             working_dir,
                                              launch_process,
                                              LLDB_INVALID_PROCESS_ID,
-                                             NULL, false,
+                                             NULL, 
+                                             false,
                                              launch_flags,
                                              inferior_arch);
             if (error.Fail())
@@ -644,6 +652,9 @@
                                          NULL,                      // inferior_argv
                                          NULL,                      // inferior_envp
                                          NULL,                      // stdin_path
+                                         NULL,                      // stdout_path
+                                         NULL,                      // stderr_path
+                                         NULL,                      // working_dir
                                          false,                     // launch_process == false (we are attaching)
                                          LLDB_INVALID_PROCESS_ID,   // Don't send any attach to pid options to debugserver
                                          NULL,                      // Don't send any attach by process name option to debugserver
@@ -746,6 +757,9 @@
                                          NULL,                      // inferior_argv
                                          NULL,                      // inferior_envp
                                          NULL,                      // stdin_path
+                                         NULL,                      // stdout_path
+                                         NULL,                      // stderr_path
+                                         NULL,                      // working_dir
                                          false,                     // launch_process == false (we are attaching)
                                          LLDB_INVALID_PROCESS_ID,   // Don't send any attach to pid options to debugserver
                                          NULL,                      // Don't send any attach by process name option to debugserver
@@ -1732,7 +1746,10 @@
     const char *debugserver_url,    // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
     char const *inferior_argv[],    // Arguments for the inferior program including the path to the inferior itself as the first argument
     char const *inferior_envp[],    // Environment to pass along to the inferior program
-    char const *stdio_path,
+    const char *stdin_path,
+    const char *stdout_path,
+    const char *stderr_path,
+    const char *working_dir,
     bool launch_process,            // Set to true if we are going to be launching a the process
     lldb::pid_t attach_pid,         // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver
     const char *attach_name,        // Wait for the next process to launch whose basename matches "attach_name"
@@ -1824,7 +1841,13 @@
             char arg_cstr[PATH_MAX];
 
             lldb_utility::PseudoTerminal pty;
-            if (launch_process && stdio_path == NULL && m_local_debugserver && !no_stdio)
+            const char *stdio_path = NULL;
+            if (launch_process && 
+                stdin_path == NULL && 
+                stdout_path == NULL && 
+                stderr_path == NULL && 
+                m_local_debugserver &&
+                no_stdio == false)
             {
                 if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
                     stdio_path = pty.GetSlaveName (NULL, 0);
@@ -1843,14 +1866,60 @@
                 debugserver_args.AppendArguments("--disable-aslr");
             
             // Only set the inferior
-            if (launch_process && stdio_path)
+            if (launch_process)
             {
-                debugserver_args.AppendArgument("--stdio-path");
-                debugserver_args.AppendArgument(stdio_path);
+                if (no_stdio)
+                    debugserver_args.AppendArgument("--no-stdio");
+                else
+                {
+                    if (stdin_path && stdout_path && stderr_path && 
+                        strcmp(stdin_path, stdout_path) == 0 &&
+                        strcmp(stdin_path, stderr_path) == 0)
+                    {
+                        stdio_path = stdin_path;
+                        stdin_path = stdout_path = stderr_path = NULL;
+                    }
+
+                    if (stdio_path)
+                    {
+                        // All file handles to stdin, stdout, stderr are the same...
+                        debugserver_args.AppendArgument("--stdio-path");
+                        debugserver_args.AppendArgument(stdio_path);
+                    }
+                    else
+                    {
+                        if (stdin_path == NULL && (stdout_path || stderr_path))
+                            stdin_path = "/dev/null";
+
+                        if (stdout_path == NULL && (stdin_path || stderr_path))
+                            stdout_path = "/dev/null";
+
+                        if (stderr_path == NULL && (stdin_path || stdout_path))
+                            stderr_path = "/dev/null";
+
+                        if (stdin_path)
+                        {
+                            debugserver_args.AppendArgument("--stdin-path");
+                            debugserver_args.AppendArgument(stdin_path);
+                        }
+                        if (stdout_path)
+                        {
+                            debugserver_args.AppendArgument("--stdout-path");
+                            debugserver_args.AppendArgument(stdout_path);
+                        }
+                        if (stderr_path)
+                        {
+                            debugserver_args.AppendArgument("--stderr-path");
+                            debugserver_args.AppendArgument(stderr_path);
+                        }
+                    }
+                }
             }
-            else if (launch_process && no_stdio)
+
+            if (working_dir)
             {
-                debugserver_args.AppendArgument("--no-stdio");
+                debugserver_args.AppendArgument("--working-dir");
+                debugserver_args.AppendArgument(working_dir);
             }
 
             const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");