* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / fork-child.c
index 613f1eeaa10bdd0e50f93e4623e73fbb9e065130..905dd0c8b542b5ed97b349f0a2fe42f5619ad0c4 100644 (file)
@@ -24,7 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "wait.h"
 #include "gdbcore.h"
-#include "terminal.h"          /* For #ifdef TIOCGPGRP and new_tty */
+#include "serial.h" /* For job_control.  */
+#include "terminal.h"          /* For new_tty */
 
 #include <signal.h>
 
@@ -60,6 +61,7 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
   static char default_shell_file[] = SHELL_FILE;
   int len;
   int pending_execs;
+  int terminal_initted;
   /* Set debug_fork then attach to the child while it sleeps, to debug. */
   static int debug_fork = 0;
   /* This is set to the result of setpgrp, which if vforked, will be visible
@@ -96,20 +98,58 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
 #endif
   strcat (shell_command, "exec ");
 
-  /* Now add exec_file, quoting as necessary.  Quoting in this style is
-     said to work with all shells.  */
+  /* Now add exec_file, quoting as necessary.  */
   {
     char *p;
+    int need_to_quote;
 
-    strcat (shell_command, "'");
-    for (p = exec_file; *p != '\0'; ++p)
+    /* Quoting in this style is said to work with all shells.  But csh
+       on IRIX 4.0.1 can't deal with it.  So we only quote it if we need
+       to.  */
+    p = exec_file;
+    while (1)
       {
-       if (*p == '\'')
-         strcat (shell_command, "'\\''");
-       else
-         strncat (shell_command, p, 1);
+       switch (*p)
+         {
+         case '\'':
+         case '"':
+         case '(':
+         case ')':
+         case '$':
+         case '&':
+         case ';':
+         case '<':
+         case '>':
+         case ' ':
+         case '\n':
+         case '\t':
+           need_to_quote = 1;
+           goto end_scan;
+
+         case '\0':
+           need_to_quote = 0;
+           goto end_scan;
+
+         default:
+           break;
+         }
+       ++p;
+      }
+  end_scan:
+    if (need_to_quote)
+      {
+       strcat (shell_command, "'");
+       for (p = exec_file; *p != '\0'; ++p)
+         {
+           if (*p == '\'')
+             strcat (shell_command, "'\\''");
+           else
+             strncat (shell_command, p, 1);
+         }
+       strcat (shell_command, "'");
       }
-    strcat (shell_command, "'");
+    else
+      strcat (shell_command, exec_file);
   }
 
   strcat (shell_command, " ");
@@ -152,20 +192,10 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
       if (debug_fork) 
        sleep (debug_fork);
 
-#ifdef TIOCGPGRP
       /* Run inferior in a separate process group.  */
-#ifdef NEED_POSIX_SETPGID
-      debug_setpgrp = setpgid (0, 0);
-#else
-#if defined(USG) && !defined(SETPGRP_ARGS)
-      debug_setpgrp = setpgrp ();
-#else
-      debug_setpgrp = setpgrp (getpid (), getpid ());
-#endif /* USG */
-#endif /* NEED_POSIX_SETPGID */
+      debug_setpgrp = gdb_setpgid ();
       if (debug_setpgrp == -1)
         perror("setpgrp failed in child");
-#endif /* TIOCGPGRP */
 
 #ifdef SET_STACK_LIMIT_HUGE
       /* Reset the stack limit back to what it was.  */
@@ -213,6 +243,8 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
      initialize anything target-vector-specific that needs initializing.  */
   (*init_trace_fun)(pid);
 
+  init_thread_list();
+
 #ifdef CREATE_INFERIOR_HOOK
   CREATE_INFERIOR_HOOK (pid);
 #endif  
@@ -237,12 +269,7 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
 
   init_wait_for_inferior ();
 
-  /* Set up the "saved terminal modes" of the inferior
-     based on what modes we are starting it with.  */
-  target_terminal_init ();
-
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
+  terminal_initted = 0;
 
   while (1)
     {
@@ -257,6 +284,21 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
       else
        {
          /* We handle SIGTRAP, however; it means child did an exec.  */
+         if (!terminal_initted)
+           {
+             /* Now that the child has exec'd we know it has already set its
+                process group.  On POSIX systems, tcsetpgrp will fail with
+                EPERM if we try it before the child's setpgid.  */
+
+             /* Set up the "saved terminal modes" of the inferior
+                based on what modes we are starting it with.  */
+             target_terminal_init ();
+
+             /* Install inferior's terminal modes.  */
+             target_terminal_inferior ();
+
+             terminal_initted = 1;
+           }
          if (0 == --pending_execs)
            break;
          resume (0, 0);                /* Just make it go on */
This page took 0.025164 seconds and 4 git commands to generate.