diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 73e7134a8..e9ee7c864 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,21 @@
+2010-10-23  Christopher Faylor  <me+cygwin@cgf.cx>
+
+	* fhandler.h (fhandler_termios::tcinit): Make second argument
+	non-optional.
+	* fhandler_console.cc (fhandler_console::open): Specify second argument
+	to tcinit.
+	* fhandler_termios.cc (fhandler_termios::tcinit): Rename second
+	argument.  Set pgid to 0 if this is a pty master.
+	(fhandler_termios::tcgetpgrp): Just return value of pgid.  It will be
+	zero if not initialized.
+	* fhandler_tty.cc (fhandler_tty_slave::open): Specify second argument
+	to tcinit.
+	(fhandler_tty_slave::ioctl): Implement TIOCGPRP/TIOCSPGRP.  Fix switch
+	indentation.
+	(fhandler_tty_master::ioctl): Implement TIOCGPRP/TIOCSPGRP.
+	* include/sys/termios.h (TIOCGPGRP): Define similarly to Linux.
+	(TIOCSPGRP): Ditto.
+
 2010-10-18   Marco Atzeri  <marco_atzeri@yahoo.it>
 
 	* winsup/cygwin/cygwin.din: Add llround and llroundf.
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 42a0f2407..66ebc1198 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -885,7 +885,7 @@ class fhandler_termios: public fhandler_base
   HANDLE& get_output_handle () { return output_handle; }
   line_edit_status line_edit (const char *rptr, int nread, termios&);
   void set_output_handle (HANDLE h) { output_handle = h; }
-  void tcinit (tty_min *this_tc, bool force = false);
+  void tcinit (tty_min *this_tc, bool force);
   bool is_tty () const { return true; }
   int tcgetpgrp ();
   int tcsetpgrp (int pid);
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 05a0310a5..3cac714d1 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -695,7 +695,7 @@ fhandler_console::open (int flags, mode_t)
 {
   HANDLE h;
 
-  tcinit (get_tty_stuff (flags));
+  tcinit (get_tty_stuff (flags), false);
 
   set_io_handle (NULL);
   set_output_handle (NULL);
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 0f27a9838..6e0ad6777 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -23,13 +23,13 @@ details. */
 /* Common functions shared by tty/console */
 
 void
-fhandler_termios::tcinit (tty_min *this_tc, bool force)
+fhandler_termios::tcinit (tty_min *this_tc, bool is_pty_master)
 {
   /* Initial termios values */
 
   tc = this_tc;
 
-  if (force || !tc->initialized ())
+  if (is_pty_master || !tc->initialized ())
     {
       tc->ti.c_iflag = BRKINT | ICRNL | IXON;
       tc->ti.c_oflag = OPOST | ONLCR;
@@ -55,7 +55,7 @@ fhandler_termios::tcinit (tty_min *this_tc, bool force)
       tc->ti.c_cc[VWERASE]	= CWERASE;
 
       tc->ti.c_ispeed = tc->ti.c_ospeed = B38400;
-      tc->pgid = myself->pgid;
+      tc->pgid = is_pty_master ? 0 : myself->pgid;
       tc->initialized (true);
     }
 }
@@ -108,7 +108,7 @@ fhandler_termios::tcgetpgrp ()
 int
 fhandler_pty_master::tcgetpgrp ()
 {
-  return myself->ctty != -1 && myself->ctty == tc->ntty ? tc->pgid : 0;
+  return tc->pgid;
 }
 
 void
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 59c7345e8..898469750 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -484,7 +484,7 @@ fhandler_tty_slave::open (int flags, mode_t)
       goto out;
     }
 
-  tcinit (cygwin_shared->tty[get_unit ()]);
+  tcinit (cygwin_shared->tty[get_unit ()], false);
 
   cygwin_shared->tty.attach (get_unit ());
 
@@ -1065,6 +1065,21 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
       set_nonblocking (*(int *) arg);
       retval = 0;
       goto out;
+    case TIOCGPGRP:
+      {
+	pid_t pid = this->tcgetpgrp ();
+	if (pid < 0)
+	  retval = -1;
+	else
+	  {
+	    *((pid_t *) arg) = pid;
+	    retval = 0;
+	  }
+      }
+      goto out;
+    case TIOCSPGRP:
+      retval = this->tcsetpgrp ((pid_t) arg);
+      goto out;
     default:
       set_errno (EINVAL);
       return -1;
@@ -1349,6 +1364,7 @@ fhandler_pty_master::open (int flags, mode_t)
   //
   // FIXME: Do this better someday
   fhandler_pty_master *arch = (fhandler_tty_master *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
+small_printf ("tty%d myself->sid %d myself->pid %d this->tcgetpgrp %d\n", get_unit (), myself->sid, myself->pid, this->tcgetpgrp ());
   *((fhandler_pty_master **) cygheap->fdtab.add_archetype ()) = arch;
   archetype = arch;
   *arch = *this;
@@ -1510,26 +1526,31 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
 {
   switch (cmd)
     {
-      case TIOCPKT:
-	pktmode = *(int *) arg;
-	break;
-      case TIOCGWINSZ:
-	*(struct winsize *) arg = get_ttyp ()->winsize;
-	break;
-      case TIOCSWINSZ:
-	if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
-	    || get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
-	  {
-	    get_ttyp ()->winsize = *(struct winsize *) arg;
-	    killsys (-get_ttyp ()->getpgid (), SIGWINCH);
-	  }
-	break;
-      case FIONBIO:
-	set_nonblocking (*(int *) arg);
-	break;
-      default:
-	set_errno (EINVAL);
-	return -1;
+    case TIOCPKT:
+      pktmode = *(int *) arg;
+      break;
+    case TIOCGWINSZ:
+      *(struct winsize *) arg = get_ttyp ()->winsize;
+      break;
+    case TIOCSWINSZ:
+      if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
+	  || get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
+	{
+	  get_ttyp ()->winsize = *(struct winsize *) arg;
+	  killsys (-get_ttyp ()->getpgid (), SIGWINCH);
+	}
+      break;
+    case TIOCGPGRP:
+      *((pid_t *) arg) = this->tcgetpgrp ();
+      break;
+    case TIOCSPGRP:
+      return this->tcsetpgrp ((pid_t) arg);
+    case FIONBIO:
+      set_nonblocking (*(int *) arg);
+      break;
+    default:
+      set_errno (EINVAL);
+      return -1;
     }
   return 0;
 }
diff --git a/winsup/cygwin/include/sys/termios.h b/winsup/cygwin/include/sys/termios.h
index c81d820ac..974a67404 100644
--- a/winsup/cygwin/include/sys/termios.h
+++ b/winsup/cygwin/include/sys/termios.h
@@ -348,5 +348,7 @@ struct winsize
 #define TIOCGWINSZ (('T' << 8) | 1)
 #define TIOCSWINSZ (('T' << 8) | 2)
 #define TIOCLINUX  (('T' << 8) | 3)
+#define TIOCGPGRP  (('T' << 8) | 0xf)
+#define TIOCSPGRP  (('T' << 8) | 0x10)
 
 #endif	/* _SYS_TERMIOS_H */