diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bdde07d66db..74879780ba2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+Thu Sep 30 11:30:56 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+	* fork-child.c (fork_inferior): Don't call target_terminal_init
+	and target_terminal_inferior until we are sure that the inferior
+	has called gdb_setpgid.  This fixes PR 2900 (Schauer tracked it
+	down and was able to reliably reproduce it by putting a sleep()
+	before the gdb_setpgid()).
+
 Thu Sep 30 12:00:49 1993  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
 
 	* c-exp.y, m2-exp.y:  Change type of address for msymbol to
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 8eade520bdf..905dd0c8b54 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -61,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
@@ -268,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)
     {
@@ -288,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 */