From 29ac7f89e36e5f5b46286cdbb5501bcea3ce2055 Mon Sep 17 00:00:00 2001
From: Christopher Faylor <me@cgf.cx>
Date: Thu, 7 Sep 2000 16:23:51 +0000
Subject: [PATCH] Split out tty and shared_info stuff into their own headers
 and use throughout. Include sys/termios.h for files which need it. * tty.h:
 New file. * shared_info.h: New file. * fhandler.h: Move inline methods that
 rely on tty stuff to fhandler_console.cc. * fhandler_tty.cc
 (fhandler_pty_master::process_slave_output): Set output_done_event
 immediately after reading data to speed up tty output processing.
 (process_output): Set write_error to errno or zero.
 (fhandler_tty_slave::write): Check previous write error prior to writing to
 slave end of pipe.  This allows tty output to be slightly less synchronous. *
 fhandler_console.cc (fhandler_console::tcsetpgrp): Moved here from
 fhandler.h. (fhandler_console::set_input_state): Ditto.

---
 winsup/cygwin/ChangeLog           |  19 +++
 winsup/cygwin/dcrt0.cc            |   2 +
 winsup/cygwin/exceptions.cc       |   2 +
 winsup/cygwin/external.cc         |   2 +
 winsup/cygwin/fhandler.cc         |   2 +
 winsup/cygwin/fhandler.h          |  10 +-
 winsup/cygwin/fhandler_console.cc |  17 ++
 winsup/cygwin/fhandler_serial.cc  |   1 +
 winsup/cygwin/fhandler_termios.cc |   1 +
 winsup/cygwin/fhandler_tty.cc     |  39 +++--
 winsup/cygwin/heap.cc             |   2 +
 winsup/cygwin/ioctl.cc            |   1 +
 winsup/cygwin/passwd.cc           |   1 +
 winsup/cygwin/path.cc             |   2 +
 winsup/cygwin/registry.cc         |   2 +
 winsup/cygwin/select.cc           |   1 +
 winsup/cygwin/shared.cc           |   2 +
 winsup/cygwin/shared.h            | 256 ------------------------------
 winsup/cygwin/shared_info.h       | 130 +++++++++++++++
 winsup/cygwin/sigproc.cc          |   2 +
 winsup/cygwin/syscalls.cc         |   2 +
 winsup/cygwin/termios.cc          |  37 ++---
 winsup/cygwin/tty.cc              |   2 +
 winsup/cygwin/tty.h               | 143 +++++++++++++++++
 24 files changed, 371 insertions(+), 307 deletions(-)
 create mode 100644 winsup/cygwin/shared_info.h
 create mode 100644 winsup/cygwin/tty.h

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 186bad32a..dacf7aae6 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,22 @@
+Thu Sep  7 12:14:43 2000  Christopher Faylor <cgf@cygnus.com>
+
+	Split out tty and shared_info stuff into their own headers and use
+	throughout.  Include sys/termios.h for files which need it.
+	* tty.h: New file.
+	* shared_info.h: New file.
+	* fhandler.h: Move inline methods that rely on tty stuff to
+	fhandler_console.cc.
+	* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Set
+	output_done_event immediately after reading data to speed up tty output
+	processing.
+	(process_output): Set write_error to errno or zero.
+	(fhandler_tty_slave::write): Check previous write error prior to
+	writing to slave end of pipe.  This allows tty output to be slightly
+	less synchronous.
+	* fhandler_console.cc (fhandler_console::tcsetpgrp): Moved here from
+	fhandler.h.
+	(fhandler_console::set_input_state): Ditto.
+
 Wed Sep  6 21:11:13 2000  Christopher Faylor <cgf@cygnus.com>
 
 	* exceptions.cc (signal_exit): Reset all mutos owned by the main
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 3c02ee2b2..4121d89f9 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -28,6 +28,8 @@ details. */
 #include "path.h"
 #include "dtable.h"
 #include "thread.h"
+#include "tty.h"
+#include "shared_info.h"
 
 #define MAX_AT_FILE_LEVEL 10
 
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 3395a1eea..8b133cc8c 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -20,6 +20,8 @@ details. */
 #include "cygerrno.h"
 #include "thread.h"
 #include "perthread.h"
+#include "tty.h"
+#include "shared_info.h"
 
 char debugger_command[2 * MAX_PATH + 20];
 
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index bfc4f1b25..64a3acf02 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -16,6 +16,8 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include <exceptions.h>
+#include "tty.h"
+#include "shared_info.h"
 
 static external_pinfo *
 fillout_pinfo (pid_t pid, int winpid)
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index c69d5f316..e5a903c37 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -18,6 +18,8 @@ details. */
 #include "cygerrno.h"
 #include "fhandler.h"
 #include "path.h"
+#include "tty.h"
+#include "shared_info.h"
 
 static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
 
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index a7f942a7e..b25665873 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -511,6 +511,8 @@ public:
 #define release_output_mutex() \
   __release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
 
+class tty;
+class tty_min;
 class fhandler_termios: public fhandler_base
 {
 protected:
@@ -594,7 +596,7 @@ public:
   int tcsetattr (int a, const struct termios *t);
   int tcgetattr (struct termios *t);
 
-  int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
+  int tcsetpgrp (const pid_t pid);
 
   /* Special dup as we must dup two handles */
   int dup (fhandler_base *child);
@@ -609,11 +611,7 @@ public:
   void fixup_after_exec (HANDLE);
   void set_close_on_exec (int val);
   void fixup_after_fork (HANDLE parent);
-  void set_input_state ()
-  {
-    if (TTYISSETF (RSTCONS))
-      input_tcsetattr (0, &tc->ti);
-  }
+  void set_input_state ();
 };
 
 class fhandler_tty_common: public fhandler_termios
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 33bf18b58..ff70bb4b0 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -24,6 +24,8 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include "tty.h"
+#include "shared_info.h"
 
 /*
  * Scroll the screen context.
@@ -249,6 +251,21 @@ fhandler_console::read (void *pv, size_t buflen)
   return copied_chars;
 }
 
+int
+fhandler_console::tcsetpgrp (pid_t pid)
+{
+  tc->pgid = pid;
+  return 0;
+}
+
+void
+fhandler_console::set_input_state ()
+{
+  if (TTYISSETF (RSTCONS))
+    input_tcsetattr (0, &tc->ti);
+}
+
+
 static struct
   {
     SHORT winTop;
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
index e68e34e11..1f31cd61e 100644
--- a/winsup/cygwin/fhandler_serial.cc
+++ b/winsup/cygwin/fhandler_serial.cc
@@ -18,6 +18,7 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include <sys/termios.h>
 
 /**********************************************************************/
 /* fhandler_serial */
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 486e47918..72b2e998d 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -19,6 +19,7 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include "tty.h"
 
 /* Common functions shared by tty/console */
 
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 6c7e3605e..c78f2bad6 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -23,6 +23,8 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include "cygheap.h"
+#include "tty.h"
+#include "shared_info.h"
 
 /* Tty master stuff */
 
@@ -285,14 +287,12 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
 	}
 
       termios_printf ("bytes read %u", n);
+      get_ttyp ()->write_error = 0;
+      if (output_done_event != NULL)
+	SetEvent (output_done_event);
 
       if (get_ttyp ()->ti.c_lflag & FLUSHO)
-	{
-	  get_ttyp ()->write_retval = n;
-	  if (output_done_event != NULL)
-	    SetEvent (output_done_event);
-	  continue;
-	}
+	continue;
 
       char *optr;
       optr = buf;
@@ -389,8 +389,7 @@ process_output (void *)
 	  ExitThread (0);
 	}
       n = tty_master->console->write ((void *) buf, (size_t) n);
-      tty_master->get_ttyp ()->write_retval = n == -1 ? -get_errno () : n;
-      SetEvent (tty_master->output_done_event);
+      tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
     }
 }
 
@@ -554,6 +553,16 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
       ptr = (char *) ptr + n;
       len -= n;
 
+      /* Previous write may have set write_error to != 0.  Check it here.
+	 This is less than optimal, but the alternative slows down tty
+	 writes enormously. */
+      if (get_ttyp ()->write_error)
+	{
+	  set_errno (get_ttyp ()->write_error);
+	  towrite = (DWORD) -1;
+	  break;
+	}
+
       if (WriteFile (get_output_handle (), buf, n, &n, NULL) == FALSE)
 	{
 	  DWORD err = GetLastError ();
@@ -577,13 +586,6 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
 	  rc = WaitForSingleObject (output_done_event, x);
 	  termios_printf("waited %d ms for output_done_event, WFSO %d", x, rc);
 	}
-
-      if (get_ttyp ()->write_retval < 0)
-	{
-	  set_errno (-get_ttyp ()->write_retval);
-	  towrite = (DWORD) -1;
-	  break;
-	}
     }
   release_output_mutex ();
   return towrite;
@@ -931,12 +933,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
 int
 fhandler_pty_master::read (void *ptr, size_t len)
 {
-  int x = process_slave_output ((char *) ptr, len, pktmode);
-
-  if (output_done_event != NULL)
-    SetEvent (output_done_event);
-
-  return x;
+  return process_slave_output ((char *) ptr, len, pktmode);
 }
 
 int
diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc
index d1408eb7b..1ad80a2a5 100644
--- a/winsup/cygwin/heap.cc
+++ b/winsup/cygwin/heap.cc
@@ -15,6 +15,8 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include "heap.h"
+#include "tty.h"
+#include "shared_info.h"
 
 #define assert(x)
 
diff --git a/winsup/cygwin/ioctl.cc b/winsup/cygwin/ioctl.cc
index 5e198b828..50bed772b 100644
--- a/winsup/cygwin/ioctl.cc
+++ b/winsup/cygwin/ioctl.cc
@@ -17,6 +17,7 @@ details. */
 #include "cygerrno.h"
 #include "fhandler.h"
 #include "dtable.h"
+#include <sys/termios.h>
 
 extern "C" int
 ioctl (int fd, int cmd, void *buf)
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index a29a8a433..29e912699 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -20,6 +20,7 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include <sys/termios.h>
 
 /* Read /etc/passwd only once for better performance.  This is done
    on the first call that needs information from it. */
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index f322a6fa7..307ab62e1 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -65,6 +65,8 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include "cygheap.h"
+#include "tty.h"
+#include "shared_info.h"
 
 static int normalize_win32_path (const char *src, char *dst);
 static void slashify (const char *src, char *dst, int trailing_slash_p);
diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc
index ebe6bb3c6..82acc6981 100644
--- a/winsup/cygwin/registry.cc
+++ b/winsup/cygwin/registry.cc
@@ -9,6 +9,8 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include "winsup.h"
+#include "tty.h"
+#include "shared_info.h"
 
 char cygnus_class[] = "cygnus";
 
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index c7181fb53..b52471a0e 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -39,6 +39,7 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "perthread.h"
+#include "tty.h"
 
 /*
  * All these defines below should be in sys/types.h
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 1cb8e6e9c..aab2b1a9e 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -17,6 +17,8 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include "tty.h"
+#include "shared_info.h"
 
 #define SHAREDVER (unsigned)(cygwin_version.api_major << 16 | \
 		   cygwin_version.api_minor)
diff --git a/winsup/cygwin/shared.h b/winsup/cygwin/shared.h
index ed0b83fc3..bd88ca772 100644
--- a/winsup/cygwin/shared.h
+++ b/winsup/cygwin/shared.h
@@ -80,270 +80,14 @@ public:
 char *__stdcall get_registry_hive_path (const PSID psid, char *path);
 void __stdcall load_registry_hive (PSID psid);
 
-/******** Mount Table ********/
-
-/* Mount table entry */
-
-class mount_item
-{
-public:
-  /* FIXME: Nasty static allocation.  Need to have a heap in the shared
-     area [with the user being able to configure at runtime the max size].  */
-
-  /* Win32-style mounted partition source ("C:\foo\bar").
-     native_path[0] == 0 for unused entries.  */
-  char native_path[MAX_PATH];
-  int native_pathlen;
-
-  /* POSIX-style mount point ("/foo/bar") */
-  char posix_path[MAX_PATH];
-  int posix_pathlen;
-
-  unsigned flags;
-
-  void init (const char *dev, const char *path, unsigned flags);
-
-  struct mntent *getmntent ();
-};
-
-/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
-   higher numbered registry entries.  Don't change this number willy-nilly.
-   What we need is to have a more dynamic allocation scheme, but the current
-   scheme should be satisfactory for a long while yet.  */
-#define MAX_MOUNTS 30
-
-class mount_info
-{
-  int posix_sorted[MAX_MOUNTS];
-  int native_sorted[MAX_MOUNTS];
-public:
-  int nmounts;
-  mount_item mount[MAX_MOUNTS];
-
-  /* Strings used by getmntent(). */
-  char mnt_type[20];
-  char mnt_opts[20];
-  char mnt_fsname[MAX_PATH];
-  char mnt_dir[MAX_PATH];
-
-  /* cygdrive_prefix is used as the root of the path automatically
-     prepended to a path when the path has no associated mount.
-     cygdrive_flags are the default flags for the cygdrives. */
-  char cygdrive[MAX_PATH];
-  size_t cygdrive_len;
-  unsigned cygdrive_flags;
-
-  /* Increment when setting up a reg_key if mounts area had to be
-     created so we know when we need to import old mount tables. */
-  int had_to_create_mount_areas;
-
-  void init ();
-  int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
-  int del_item (const char *path, unsigned flags, int reg_p);
-
-  void from_registry ();
-  int add_reg_mount (const char * native_path, const char * posix_path,
-		      unsigned mountflags);
-  int del_reg_mount (const char * posix_path, unsigned mountflags);
-
-  unsigned set_flags_from_win32_path (const char *path);
-  int conv_to_win32_path (const char *src_path, char *win32_path,
-			  char *full_win32_path, DWORD &devn, int &unit,
-			  unsigned *flags = NULL);
-  int conv_to_posix_path (const char *src_path, char *posix_path,
-			  int keep_rel_p);
-  struct mntent *getmntent (int x);
-
-  int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
-  int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
-  int get_cygdrive_prefixes (char *user, char *system);
-
-  void import_v1_mounts ();
-
-private:
-
-  void sort ();
-  void read_mounts (reg_key& r);
-  void read_v1_mounts (reg_key r, unsigned which);
-  void mount_slash ();
-  void to_registry ();
-
-  int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
-  void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
-  void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
-  void read_cygdrive_info_from_registry ();
-};
-
-/******** TTY Support ********/
-
-/* tty tables */
-
-#define INP_BUFFER_SIZE 256
-#define OUT_BUFFER_SIZE 256
-#define NTTYS		128
-#define TTY_CONSOLE	0x40000000
-#define tty_attached(p)	((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
-
-/* Input/Output/ioctl events */
-
-#define OUTPUT_DONE_EVENT	"cygtty%d.output.done"
-#define IOCTL_REQUEST_EVENT	"cygtty%d.ioctl.request"
-#define IOCTL_DONE_EVENT	"cygtty%d.ioctl.done"
-#define RESTART_OUTPUT_EVENT	"cygtty%d.output.restart"
-#define OUTPUT_MUTEX		"cygtty%d.output.mutex"
-#define TTY_SLAVE_ALIVE		"cygtty%x.slave_alive"
-#define TTY_MASTER_ALIVE	"cygtty%x.master_alive"
-
-#include <sys/termios.h>
-
-enum
-{
-  TTY_INITIALIZED = 1,		/* Set if tty is initialized */
-  TTY_RSTCONS = 2		/* Set if console needs to be set to "non-cooked" */
-};
-
-#define TTYISSETF(x)	__ISSETF (tc, x, TTY)
-#define TTYSETF(x)	__SETF (tc, x, TTY)
-#define TTYCLEARF(x)	__CLEARF (tc, x, TTY)
-#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
-
-#ifndef MIN_CTRL_C_SLOP
-#define MIN_CTRL_C_SLOP 50
-#endif
-
-class tty_min
-{
-  pid_t sid;	/* Session ID of tty */
-public:
-  DWORD status;
-  pid_t pgid;
-  int OutputStopped;
-  int ntty;
-  DWORD last_ctrl_c;	// tick count of last ctrl-c
-
-  tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
-  void setntty (int n) {ntty = n;}
-  pid_t getpgid () {return pgid;}
-  void setpgid (int pid) {pgid = pid;}
-  int getsid () {return sid;}
-  void setsid (pid_t tsid) {sid = tsid;}
-  struct termios ti;
-  struct winsize winsize;
-
-  /* ioctl requests buffer */
-  int cmd;
-  union
-  {
-    struct termios termios;
-    struct winsize winsize;
-    int value;
-    pid_t pid;
-  } arg;
-  /* XXX_retval variables holds master's completion codes. Error are stored as
-   * -ERRNO
-   */
-  int ioctl_retval;
-
-  int write_retval;
-};
-
-class fhandler_pty_master;
-
-class tty: public tty_min
-{
-  HANDLE get_event (const char *fmt, BOOL inherit);
-public:
-  HWND  hwnd;	/* Console window handle tty belongs to */
-
-  DWORD master_pid;	/* Win32 PID of tty master process */
-
-  HANDLE from_master, to_slave;
-  HANDLE from_slave, to_master;
-
-  int read_retval;
-  BOOL was_opened;	/* True if opened at least once. */
-
-  void init ();
-  HANDLE create_inuse (const char *);
-  BOOL common_init (fhandler_pty_master *);
-  BOOL alive (const char *fmt);
-  BOOL slave_alive ();
-  BOOL master_alive ();
-  HWND gethwnd () {return hwnd;}
-  void sethwnd (HWND wnd) {hwnd = wnd;}
-  int make_pipes (fhandler_pty_master *ptym);
-  HANDLE open_output_mutex (BOOL inherit = FALSE)
-  {
-    char buf[80];
-    __small_sprintf (buf, OUTPUT_MUTEX, ntty);
-    return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
-  }
-  BOOL exists ()
-  {
-    HANDLE h = open_output_mutex ();
-    if (h)
-      {
-	CloseHandle (h);
-	return 1;
-      }
-    return slave_alive ();
-  }
-};
-
-class tty_list
-{
-  tty ttys[NTTYS];
-
-public:
-  tty * operator [](int n) {return ttys + n;}
-  int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
-  int connect_tty (int);
-  void terminate ();
-  void init ();
-  tty_min *get_tty (int n);
-};
-
-void __stdcall tty_init ();
-void __stdcall tty_terminate ();
-int __stdcall attach_tty (int);
-void __stdcall create_tty_master (int);
-extern "C" int ttyslot (void);
-
-/******** Shared Info ********/
-/* Data accessible to all tasks */
-
-class shared_info
-{
-  DWORD inited;
-
-public:
-  /* FIXME: Doesn't work if more than one user on system. */
-  mount_info mount;
-
-  int heap_chunk_in_mb;
-  unsigned heap_chunk_size (void);
-
-  tty_list tty;
-  delqueue_list delqueue;
-  void initialize (void);
-};
 
 /* Various types of security attributes for use in Create* functions. */
 extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
 extern SECURITY_ATTRIBUTES *__stdcall sec_user (PVOID sa_buf, PSID sid2 = NULL, BOOL inherit = TRUE);
 extern SECURITY_ATTRIBUTES *__stdcall sec_user_nih (PVOID sa_buf, PSID sid2 = NULL);
 
-extern shared_info *cygwin_shared;
-extern HANDLE cygwin_shared_h;
-extern HANDLE console_shared_h;
 extern int __stdcall set_console_state_for_spawn ();
 
-void __stdcall shared_init (void);
-void __stdcall shared_terminate (void);
-
-char *__stdcall shared_name (const char *, int);
-void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
-
 extern "C" {
 /* This is for programs that want to access the shared data. */
 class shared_info *cygwin_getshared (void);
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
new file mode 100644
index 000000000..52c055989
--- /dev/null
+++ b/winsup/cygwin/shared_info.h
@@ -0,0 +1,130 @@
+/* shared_sec.h: shared info for cygwin
+
+   Copyright 1998, 1999, 2000 Cygnus Solutions.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+/* Mount table entry */
+
+class mount_item
+{
+public:
+  /* FIXME: Nasty static allocation.  Need to have a heap in the shared
+     area [with the user being able to configure at runtime the max size].  */
+
+  /* Win32-style mounted partition source ("C:\foo\bar").
+     native_path[0] == 0 for unused entries.  */
+  char native_path[MAX_PATH];
+  int native_pathlen;
+
+  /* POSIX-style mount point ("/foo/bar") */
+  char posix_path[MAX_PATH];
+  int posix_pathlen;
+
+  unsigned flags;
+
+  void init (const char *dev, const char *path, unsigned flags);
+
+  struct mntent *getmntent ();
+};
+
+/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
+   higher numbered registry entries.  Don't change this number willy-nilly.
+   What we need is to have a more dynamic allocation scheme, but the current
+   scheme should be satisfactory for a long while yet.  */
+#define MAX_MOUNTS 30
+
+class mount_info
+{
+  int posix_sorted[MAX_MOUNTS];
+  int native_sorted[MAX_MOUNTS];
+public:
+  int nmounts;
+  mount_item mount[MAX_MOUNTS];
+
+  /* Strings used by getmntent(). */
+  char mnt_type[20];
+  char mnt_opts[20];
+  char mnt_fsname[MAX_PATH];
+  char mnt_dir[MAX_PATH];
+
+  /* cygdrive_prefix is used as the root of the path automatically
+     prepended to a path when the path has no associated mount.
+     cygdrive_flags are the default flags for the cygdrives. */
+  char cygdrive[MAX_PATH];
+  size_t cygdrive_len;
+  unsigned cygdrive_flags;
+
+  /* Increment when setting up a reg_key if mounts area had to be
+     created so we know when we need to import old mount tables. */
+  int had_to_create_mount_areas;
+
+  void init ();
+  int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
+  int del_item (const char *path, unsigned flags, int reg_p);
+
+  void from_registry ();
+  int add_reg_mount (const char * native_path, const char * posix_path,
+		      unsigned mountflags);
+  int del_reg_mount (const char * posix_path, unsigned mountflags);
+
+  unsigned set_flags_from_win32_path (const char *path);
+  int conv_to_win32_path (const char *src_path, char *win32_path,
+			  char *full_win32_path, DWORD &devn, int &unit,
+			  unsigned *flags = NULL);
+  int conv_to_posix_path (const char *src_path, char *posix_path,
+			  int keep_rel_p);
+  struct mntent *getmntent (int x);
+
+  int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
+  int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
+  int get_cygdrive_prefixes (char *user, char *system);
+
+  void import_v1_mounts ();
+
+private:
+
+  void sort ();
+  void read_mounts (reg_key& r);
+  void read_v1_mounts (reg_key r, unsigned which);
+  void mount_slash ();
+  void to_registry ();
+
+  int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
+  void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
+  void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
+  void read_cygdrive_info_from_registry ();
+};
+
+/******** Shared Info ********/
+/* Data accessible to all tasks */
+
+class shared_info
+{
+  DWORD inited;
+
+public:
+  /* FIXME: Doesn't work if more than one user on system. */
+  mount_info mount;
+
+  int heap_chunk_in_mb;
+  unsigned heap_chunk_size (void);
+
+  tty_list tty;
+  delqueue_list delqueue;
+  void initialize (void);
+};
+
+extern shared_info *cygwin_shared;
+extern HANDLE cygwin_shared_h;
+extern HANDLE console_shared_h;
+
+void __stdcall shared_init (void);
+void __stdcall shared_terminate (void);
+
+char *__stdcall shared_name (const char *, int);
+void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 50b8495ed..87b29c361 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -24,6 +24,8 @@ details. */
 #include "child_info.h"
 #include "perthread.h"
 #include <assert.h>
+#include "tty.h"
+#include "shared_info.h"
 
 /*
  * Convenience defines
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index c95eef38b..dd24f9787 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -32,6 +32,8 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include <unistd.h>
+#include "tty.h"
+#include "shared_info.h"
 
 extern BOOL allow_ntsec;
 
diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc
index 52fe489ee..07fa998da 100644
--- a/winsup/cygwin/termios.cc
+++ b/winsup/cygwin/termios.cc
@@ -16,10 +16,10 @@ details. */
 #include "cygerrno.h"
 #include "fhandler.h"
 #include "dtable.h"
+#include <sys/termios.h>
 
 /* tcsendbreak: POSIX 7.2.2.1 */
-extern "C"
-int
+extern "C" int
 tcsendbreak (int fd, int duration)
 {
   int res = -1;
@@ -47,8 +47,7 @@ out:
 }
 
 /* tcdrain: POSIX 7.2.2.1 */
-extern "C"
-int
+extern "C" int
 tcdrain (int fd)
 {
   int res = -1;
@@ -78,8 +77,7 @@ out:
 }
 
 /* tcflush: POSIX 7.2.2.1 */
-extern "C"
-int
+extern "C" int
 tcflush (int fd, int queue)
 {
   int res = -1;
@@ -107,8 +105,7 @@ out:
 }
 
 /* tcflow: POSIX 7.2.2.1 */
-extern "C"
-int
+extern "C" int
 tcflow (int fd, int action)
 {
   int res = -1;
@@ -136,8 +133,7 @@ out:
 }
 
 /* tcsetattr: POSIX96 7.2.1.1 */
-extern "C"
-int
+extern "C" int
 tcsetattr (int fd, int a, const struct termios *t)
 {
   int res = -1;
@@ -169,8 +165,7 @@ out:
 }
 
 /* tcgetattr: POSIX 7.2.1.1 */
-extern "C"
-int
+extern "C" int
 tcgetattr (int fd, struct termios *in_t)
 {
   int res = -1;
@@ -197,8 +192,7 @@ tcgetattr (int fd, struct termios *in_t)
 }
 
 /* tcgetpgrp: POSIX 7.2.3.1 */
-extern "C"
-int
+extern "C" int
 tcgetpgrp (int fd)
 {
   int res = -1;
@@ -215,8 +209,7 @@ tcgetpgrp (int fd)
 }
 
 /* tcsetpgrp: POSIX 7.2.4.1 */
-extern "C"
-int
+extern "C" int
 tcsetpgrp (int fd, pid_t pgid)
 {
   int res = -1;
@@ -239,24 +232,21 @@ tcsetpgrp (int fd, pid_t pgid)
 #undef cfsetispeed
 
 /* cfgetospeed: POSIX96 7.1.3.1 */
-extern "C"
-speed_t
+extern "C" speed_t
 cfgetospeed (struct termios *tp)
 {
   return __tonew_termios(tp)->c_ospeed;
 }
 
 /* cfgetispeed: POSIX96 7.1.3.1 */
-extern "C"
-speed_t
+extern "C" speed_t
 cfgetispeed (struct termios *tp)
 {
   return __tonew_termios(tp)->c_ispeed;
 }
 
 /* cfsetospeed: POSIX96 7.1.3.1 */
-extern "C"
-int
+extern "C" int
 cfsetospeed (struct termios *in_tp, speed_t speed)
 {
   struct termios *tp = __tonew_termios (in_tp);
@@ -266,8 +256,7 @@ cfsetospeed (struct termios *in_tp, speed_t speed)
 }
 
 /* cfsetispeed: POSIX96 7.1.3.1 */
-extern "C"
-int
+extern "C" int
 cfsetispeed (struct termios *in_tp, speed_t speed)
 {
   struct termios *tp = __tonew_termios (in_tp);
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index d619a030c..4dbe72c1a 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -20,6 +20,8 @@ details. */
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
+#include "tty.h"
+#include "shared_info.h"
 
 extern fhandler_tty_master *tty_master;
 
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
new file mode 100644
index 000000000..f4fa67102
--- /dev/null
+++ b/winsup/cygwin/tty.h
@@ -0,0 +1,143 @@
+/* tty.h: shared info for cygwin
+
+   Copyright 2000 Cygnus Solutions.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+
+/* tty tables */
+
+#define INP_BUFFER_SIZE 256
+#define OUT_BUFFER_SIZE 256
+#define NTTYS		128
+#define TTY_CONSOLE	0x40000000
+#define tty_attached(p)	((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
+
+/* Input/Output/ioctl events */
+
+#define OUTPUT_DONE_EVENT	"cygtty%d.output.done"
+#define IOCTL_REQUEST_EVENT	"cygtty%d.ioctl.request"
+#define IOCTL_DONE_EVENT	"cygtty%d.ioctl.done"
+#define RESTART_OUTPUT_EVENT	"cygtty%d.output.restart"
+#define OUTPUT_MUTEX		"cygtty%d.output.mutex"
+#define TTY_SLAVE_ALIVE		"cygtty%x.slave_alive"
+#define TTY_MASTER_ALIVE	"cygtty%x.master_alive"
+
+#include <sys/termios.h>
+
+enum
+{
+  TTY_INITIALIZED = 1,		/* Set if tty is initialized */
+  TTY_RSTCONS = 2		/* Set if console needs to be set to "non-cooked" */
+};
+
+#define TTYISSETF(x)	__ISSETF (tc, x, TTY)
+#define TTYSETF(x)	__SETF (tc, x, TTY)
+#define TTYCLEARF(x)	__CLEARF (tc, x, TTY)
+#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
+
+#ifndef MIN_CTRL_C_SLOP
+#define MIN_CTRL_C_SLOP 50
+#endif
+
+class tty_min
+{
+  pid_t sid;	/* Session ID of tty */
+public:
+  DWORD status;
+  pid_t pgid;
+  int OutputStopped;
+  int ntty;
+  DWORD last_ctrl_c;	// tick count of last ctrl-c
+
+  tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
+  void setntty (int n) {ntty = n;}
+  pid_t getpgid () {return pgid;}
+  void setpgid (int pid) {pgid = pid;}
+  int getsid () {return sid;}
+  void setsid (pid_t tsid) {sid = tsid;}
+  struct termios ti;
+  struct winsize winsize;
+
+  /* ioctl requests buffer */
+  int cmd;
+  union
+  {
+    struct termios termios;
+    struct winsize winsize;
+    int value;
+    pid_t pid;
+  } arg;
+  /* XXX_retval variables holds master's completion codes. Error are stored as
+   * -ERRNO
+   */
+  int ioctl_retval;
+
+  int write_error;
+};
+
+class fhandler_pty_master;
+
+class tty: public tty_min
+{
+  HANDLE get_event (const char *fmt, BOOL inherit);
+public:
+  HWND  hwnd;	/* Console window handle tty belongs to */
+
+  DWORD master_pid;	/* Win32 PID of tty master process */
+
+  HANDLE from_master, to_slave;
+  HANDLE from_slave, to_master;
+
+  int read_retval;
+  BOOL was_opened;	/* True if opened at least once. */
+
+  void init ();
+  HANDLE create_inuse (const char *);
+  BOOL common_init (fhandler_pty_master *);
+  BOOL alive (const char *fmt);
+  BOOL slave_alive ();
+  BOOL master_alive ();
+  HWND gethwnd () {return hwnd;}
+  void sethwnd (HWND wnd) {hwnd = wnd;}
+  int make_pipes (fhandler_pty_master *ptym);
+  HANDLE open_output_mutex (BOOL inherit = FALSE)
+  {
+    char buf[80];
+    __small_sprintf (buf, OUTPUT_MUTEX, ntty);
+    return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
+  }
+  BOOL exists ()
+  {
+    HANDLE h = open_output_mutex ();
+    if (h)
+      {
+	CloseHandle (h);
+	return 1;
+      }
+    return slave_alive ();
+  }
+};
+
+class tty_list
+{
+  tty ttys[NTTYS];
+
+public:
+  tty * operator [](int n) {return ttys + n;}
+  int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
+  int connect_tty (int);
+  void terminate ();
+  void init ();
+  tty_min *get_tty (int n);
+};
+
+void __stdcall tty_init ();
+void __stdcall tty_terminate ();
+int __stdcall attach_tty (int);
+void __stdcall create_tty_master (int);
+extern "C" int ttyslot (void);