Added the ability to run a process in a shell on MacOSX currently when using
the --tty option. So you can now get shell expansion and file redirection:

(lldb) process launch --tty --shell -- *.jpg < in.txt > out.txt

Again, the "--tty" is mandatory for now until we hook this up to other 
functions. The shell is also currently hard coded to "/bin/bash" and not the
"SHELL" variable. "/bin/tcsh" was causing problems which I need to dig into.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144443 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index 4c415f5..d6bdfe1 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -169,7 +169,7 @@
         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
         if (m_opaque_sp->GetState() == eStateConnected)
         {
-            error.SetError (m_opaque_sp->Attach (pid));            
+            error.SetError (m_opaque_sp->Attach (pid, 0));            
         }
         else
         {
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 59863ed..f79d4f3 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -337,7 +337,7 @@
 
         if (sb_process.IsValid())
         {
-            error.SetError (sb_process->Attach (pid));
+            error.SetError (sb_process->Attach (pid, 0));
             // If we are doing synchronous mode, then wait for the
             // process to stop!
             if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index ae6984e..e7d392d 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -232,6 +232,8 @@
 
             if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
             {
+                m_options.launch_info.GetArchitecture() = target->GetArchitecture();
+
                 process = target->GetPlatform()->DebugProcess (m_options.launch_info, 
                                                                debugger,
                                                                target,
@@ -695,7 +697,7 @@
 
                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
                     {
-                        error = process->Attach (attach_pid);
+                        error = process->Attach (attach_pid, 0);
                         if (error.Success())
                         {
                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index c8df2e9..048555a 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -501,10 +501,10 @@
     
     if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
     {
-        const char *shell_executable = getenv("SHELL");
+        const char *shell_executable = "/bin/bash"; //getenv("SHELL");
         std::string safe_arg;
         if (launch_info.GetArchitecture().IsValid())
-            command.Printf(" -- %s -c 'exec /usr/bin/arch -arch %s ", shell_executable, launch_info.GetArchitecture().GetArchitectureName());
+            command.Printf(" -- %s -c 'exec /usr/bin/arch -arch %s", shell_executable, launch_info.GetArchitecture().GetArchitectureName());
         else
             command.Printf(" -- %s -c 'exec ", shell_executable);
         const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 2434430..8baaefc 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -443,7 +443,7 @@
             process_sp = target->CreateProcess (listener, "gdb-remote");
             
             if (process_sp)
-                error = process_sp->Attach (pid);
+                error = process_sp->Attach (pid, 2);
         }
     }
     else
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 484fe54..69fa448 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -391,7 +391,7 @@
                         assert (connect_url_len < sizeof(connect_url));
                         error = process_sp->ConnectRemote (connect_url);
                         if (error.Success())
-                            error = process_sp->Attach(pid);
+                            error = process_sp->Attach(pid, 0);
                     }
                 }
             }
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index b85679d..d22c79d 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -2186,24 +2186,33 @@
         
         case eStateStopped:
         case eStateCrashed:
-        {
-            // During attach, prior to sending the eStateStopped event, 
-            // lldb_private::Process subclasses must set the process must set
-            // the new process ID.
-            assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
-            m_process->CompleteAttach ();
-            return eEventActionSuccess;
-        }
-            
-            
+            {
+                // During attach, prior to sending the eStateStopped event, 
+                // lldb_private::Process subclasses must set the process must set
+                // the new process ID.
+                assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID);
+                if (m_exec_count > 0)
+                {
+                    --m_exec_count;
+                    m_process->Resume();
+                    return eEventActionRetry;
+                }
+                else
+                {
+                    m_process->CompleteAttach ();
+                    return eEventActionSuccess;
+                }
+            }
             break;
+
         default:
         case eStateExited:   
         case eStateInvalid:
-            m_exit_string.assign ("No valid Process");
-            return eEventActionExit;
             break;
     }
+
+    m_exit_string.assign ("No valid Process");
+    return eEventActionExit;
 }
 
 Process::NextEventAction::EventActionResult
@@ -2219,7 +2228,7 @@
 }
 
 Error
-Process::Attach (lldb::pid_t attach_pid)
+Process::Attach (lldb::pid_t attach_pid, uint32_t exec_count)
 {
 
     m_abi_sp.reset();
@@ -2236,7 +2245,8 @@
         error = DoAttachToProcessWithID (attach_pid);
         if (error.Success())
         {
-            SetNextEventAction(new Process::AttachCompletionHandler(this));
+            
+            SetNextEventAction(new Process::AttachCompletionHandler(this, exec_count));
             StartPrivateStateThread();
         }
         else
@@ -2316,7 +2326,7 @@
             }
             else
             {
-                SetNextEventAction(new Process::AttachCompletionHandler(this));
+                SetNextEventAction(new Process::AttachCompletionHandler(this, 0));
                 StartPrivateStateThread();
             }
         }
@@ -2806,8 +2816,10 @@
             case NextEventAction::eEventActionSuccess:
                 SetNextEventAction(NULL);
                 break;
+
             case NextEventAction::eEventActionRetry:
                 break;
+
             case NextEventAction::eEventActionExit:
                 // Handle Exiting Here.  If we already got an exited event,
                 // we should just propagate it.  Otherwise, swallow this event,