From c3a9063f838124aa2a00600ad040dacd53a96cb5 Mon Sep 17 00:00:00 2001
From: Christopher Faylor <me@cgf.cx>
Date: Sun, 12 Jun 2011 20:15:26 +0000
Subject: [PATCH] Rename FH_BAD to FH_NADA throughout. * devices.h (FH_ERROR):
 New value. (iscons_dev): Extend to detect all the console device types. *
 devices.in: Set aside storage for FH_ERROR. * dtable.cc
 (dtable::init_std_file_from_handle): Use iscons_dev to detect when device is
 a console. (fh_alloc): Pass device to console constructor. (build_fh_pc):
 Short circuit when we detect that the constructor saw an error. * fhandler.h
 (fhandler_console::fhandler_console): Accept fh_devices parameter.
 (get_tty_stuff): Change to void. * fhandler_console
 (fhandler_console::set_unit): Set device to FH_ERROR on attempt to access
 anything other than the current console. (fhandler_console::get_tty_stuff):
 Change to void return. (fhandler_console::open): Return EPERM on FH_ERROR
 device type. (fhandler_console::fhandler_console): Set the device type
 appropriately before calling get_tty_stuff and rely on that function to reset
 it if necessary.

---
 winsup/cygwin/ChangeLog               | 22 ++++++++++++++++++
 winsup/cygwin/devices.cc              |  5 ++++-
 winsup/cygwin/devices.h               |  9 ++++++--
 winsup/cygwin/devices.in              |  5 ++++-
 winsup/cygwin/dtable.cc               | 13 ++++++-----
 winsup/cygwin/fhandler.h              |  4 ++--
 winsup/cygwin/fhandler_console.cc     | 32 ++++++++++++++++++++-------
 winsup/cygwin/fhandler_proc.cc        |  6 ++---
 winsup/cygwin/fhandler_process.cc     |  2 +-
 winsup/cygwin/fhandler_procnet.cc     |  2 +-
 winsup/cygwin/fhandler_procsysvipc.cc |  2 +-
 winsup/cygwin/fhandler_tty.cc         |  2 +-
 winsup/cygwin/mount.cc                |  2 +-
 13 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3031e8dbb..6b01b5c24 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,25 @@
+2011-06-12  Christopher Faylor  <me.cygwin2011@cgf.cx>
+
+	Rename FH_BAD to FH_NADA throughout.
+	* devices.h (FH_ERROR): New value.
+	(iscons_dev): Extend to detect all the console device types.
+	* devices.in: Set aside storage for FH_ERROR.
+	* dtable.cc (dtable::init_std_file_from_handle): Use iscons_dev to
+	detect when device is a console.
+	(fh_alloc): Pass device to console constructor.
+	(build_fh_pc): Short circuit when we detect that the constructor saw an
+	error.
+	* fhandler.h (fhandler_console::fhandler_console): Accept fh_devices
+	parameter.
+	(get_tty_stuff): Change to void.
+	* fhandler_console (fhandler_console::set_unit): Set device to FH_ERROR
+	on attempt to access anything other than the current console.
+	(fhandler_console::get_tty_stuff): Change to void return.
+	(fhandler_console::open): Return EPERM on FH_ERROR device type.
+	(fhandler_console::fhandler_console): Set the device type appropriately
+	before calling get_tty_stuff and rely on that function to reset it if
+	necessary.
+
 2011-06-10  Christopher Faylor  <me.cygwin2011@cgf.cx>
 
 	* environ.cc (create_upcaseenv): Delete.
diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc
index 68f402b65..26024432b 100644
--- a/winsup/cygwin/devices.cc
+++ b/winsup/cygwin/devices.cc
@@ -60,7 +60,10 @@ const device dev_dgram_storage =
   {"", {FH_DGRAM}, ""};
 
 const device dev_bad_storage =
-  {"", {FH_BAD}, ""};
+  {"", {FH_NADA}, ""};
+
+const device dev_error_storage =
+  {"", {FH_ERROR}, ""};
 #define BRACK(x) {devn_int: x}
 
 static const device dev_storage[] =
diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h
index b03364494..f1e620b59 100644
--- a/winsup/cygwin/devices.h
+++ b/winsup/cygwin/devices.h
@@ -247,7 +247,8 @@ enum fh_devices
   FH_STREAM = FHDEV (DEV_TCP_MAJOR, 121),
   FH_DGRAM = FHDEV (DEV_TCP_MAJOR, 122),
 
-  FH_BAD     = FHDEV (0, 0)
+  FH_NADA     = FHDEV (0, 0),
+  FH_ERROR   = FHDEV (255, 255)	/* Set by fh constructor when error detected */
 };
 
 struct device
@@ -348,7 +349,11 @@ extern const device dev_fs_storage;
 #define isvirtual_dev(devn) \
   (isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE)
 
-#define iscons_dev(n)  (device::major (n) == DEV_CONS_MAJOR)
+#define iscons_dev(n) \
+  ((device::major ((int) (n)) == DEV_CONS_MAJOR) \
+   || (((int) n) == FH_CONSOLE) \
+   || (((int) n) == FH_CONIN) \
+   || (((int) n) == FH_CONOUT))
 
 #define istty_slave_dev(n) (device::major (n) == DEV_TTYS_MAJOR)
 #endif /*_DEVICES_H*/
diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in
index 3b45840c4..3499b5b4c 100644
--- a/winsup/cygwin/devices.in
+++ b/winsup/cygwin/devices.in
@@ -56,7 +56,10 @@ const device dev_dgram_storage =
   {"", {FH_DGRAM}, ""};
 
 const device dev_bad_storage =
-  {"", {FH_BAD}, ""};
+  {"", {FH_NADA}, ""};
+
+const device dev_error_storage =
+  {"", {FH_ERROR}, ""};
 #define BRACK(x) {devn_int: x}
 
 %storage_here
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 9f09c01b6..6430e7523 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -351,7 +351,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
       /* Console windows are not kernel objects, so the access mask returned
 	 by NtQueryInformationFile is meaningless.  CMD always hands down
 	 stdin handles as R/O handles, but our tty slave sides are R/W. */
-      if (dev == FH_TTY || dev == FH_CONSOLE || dev.get_major () == DEV_TTYS_MAJOR)
+      if (dev == FH_TTY || iscons_dev (dev) || dev.get_major () == DEV_TTYS_MAJOR)
 	access |= GENERIC_READ | GENERIC_WRITE;
       else if (NT_SUCCESS (NtQueryInformationFile (handle, &io, &fai,
 						   sizeof fai,
@@ -460,7 +460,7 @@ fh_alloc (device dev)
       fh = cnew (fhandler_serial) ();
       break;
     case DEV_CONS_MAJOR:
-      fh = cnew (fhandler_console) ();
+      fh = cnew (fhandler_console) (dev);
       break;
     default:
       switch ((int) dev)
@@ -468,7 +468,7 @@ fh_alloc (device dev)
 	case FH_CONSOLE:
 	case FH_CONIN:
 	case FH_CONOUT:
-	  fh = cnew (fhandler_console) ();
+	  fh = cnew (fhandler_console) (dev);
 	  break;
 	case FH_PTYM:
 	  fh = cnew (fhandler_pty_master) ();
@@ -541,7 +541,7 @@ fh_alloc (device dev)
 	case FH_TTY:
 	  {
 	    if (iscons_dev (myself->ctty))
-	      fh = cnew (fhandler_console) ();
+	      fh = cnew (fhandler_console) (dev);
 	    else
 	      fh = cnew (fhandler_tty_slave) (myself->ctty);
 	    break;
@@ -564,7 +564,9 @@ build_fh_pc (path_conv& pc, bool set_name)
 
   if (!fh)
     set_errno (EMFILE);
-  else if (fh->dev () != FH_BAD)
+  else if (fh->dev () == FH_ERROR)
+    goto out;
+  else if (fh->dev () != FH_NADA)
     fh->set_name (fh->dev ().name);
   else if (set_name)
     fh->set_name (pc);
@@ -582,6 +584,7 @@ build_fh_pc (path_conv& pc, bool set_name)
       *cygheap->fdtab.add_archetype () = fh->archetype;
     }
 
+out:
   debug_printf ("fh %p", fh);
   return fh;
 }
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index d62a75255..70c882117 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1087,7 +1087,7 @@ private:
   tty_min *tc () const {return &(shared_console_info->tty_min_state);}
 
  public:
-  fhandler_console ();
+  fhandler_console (fh_devices);
   static console_state *open_shared_console (HWND hw, HANDLE& h)
   {
     bool createit = false;
@@ -1124,7 +1124,7 @@ private:
   void set_close_on_exec (bool val);
   void set_input_state ();
   void send_winch_maybe ();
-  tty_min *get_tty_stuff ();
+  void get_tty_stuff ();
   bool set_unit ();
   static bool need_invisible ();
   static bool has_a () {return !invisible_console;}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 5082da316..690930453 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -131,8 +131,18 @@ bool
 fhandler_console::set_unit ()
 {
   bool created;
+  fh_devices devset;
   if (shared_console_info)
-    created = false;
+    {
+      fh_devices this_unit = dev ();
+      fh_devices shared_unit = 
+	(fh_devices) shared_console_info->tty_min_state.getntty ();
+      created = false;
+      devset = (shared_unit == this_unit || this_unit == FH_CONSOLE
+		|| this_unit == FH_CONIN || this_unit == FH_CONOUT
+		|| this_unit == FH_TTY) ?
+		shared_unit : FH_ERROR;
+    }
   else
     {
       HWND me = GetConsoleWindow ();
@@ -144,14 +154,15 @@ fhandler_console::set_unit ()
 	  lock_ttys here;
 	  shared_console_info->tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me));
 	}
+      devset = (fh_devices) shared_console_info->tty_min_state.getntty ();
     }
 
+  dev ().parse (devset);
   return created;
 }
 
-/* Allocate and initialize the shared record for the current console.
-   Returns a pointer to shared_console_info. */
-tty_min *
+/* Allocate and initialize the shared record for the current console. */
+void
 fhandler_console::get_tty_stuff ()
 {
   if (set_unit ())
@@ -182,8 +193,6 @@ fhandler_console::get_tty_stuff ()
 	dev_state.backspace_keycode = CERASE;
 	shared_console_info->tty_min_state.sethwnd ((HWND) INVALID_HANDLE_VALUE);
       }
-
-  return &shared_console_info->tty_min_state;
 }
 
 /* Return the tty structure associated with a given tty number.  If the
@@ -756,6 +765,12 @@ fhandler_console::open (int flags, mode_t)
 {
   HANDLE h;
 
+  if (dev () == FH_ERROR)
+    {
+      set_errno (EPERM);	/* constructor found an error */
+      return 0;
+    }
+
   tcinit (false);
 
   set_io_handle (NULL);
@@ -1033,11 +1048,12 @@ fhandler_console::tcgetattr (struct termios *t)
   return res;
 }
 
-fhandler_console::fhandler_console () :
+fhandler_console::fhandler_console (fh_devices unit) :
   fhandler_termios ()
 {
+  if (unit > 0)
+    dev ().parse (unit);
   get_tty_stuff ();
-  dev ().parse (shared_console_info->tty_min_state.getntty ());
   trunc_buf.len = 0;
 }
 
diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc
index 1318ffd3e..9310696bc 100644
--- a/winsup/cygwin/fhandler_proc.cc
+++ b/winsup/cygwin/fhandler_proc.cc
@@ -68,7 +68,7 @@ static const virt_tab_t proc_tab[] = {
   { _VN ("sysvipc"),	 FH_PROCSYSVIPC,	virt_directory,	NULL },
   { _VN ("uptime"),	 FH_PROC,	virt_file,	format_proc_uptime },
   { _VN ("version"),	 FH_PROC,	virt_file,	format_proc_version },
-  { NULL, 0,	   	 FH_BAD,	virt_none,	NULL }
+  { NULL, 0,	   	 FH_NADA,	virt_none,	NULL }
 };
 
 #define PROC_DIR_COUNT 4
@@ -96,7 +96,7 @@ virt_tab_t *
 virt_tab_search (const char *path, bool prefix, const virt_tab_t *table,
 		 size_t nelem)
 {
-  virt_tab_t key = { path, 0, FH_BAD, virt_none, NULL };
+  virt_tab_t key = { path, 0, FH_NADA, virt_none, NULL };
   virt_tab_t *entry = (virt_tab_t *) bsearch (&key, table, nelem,
 					      sizeof (virt_tab_t),
 					      proc_tab_cmp);
@@ -141,7 +141,7 @@ fhandler_proc::get_proc_fhandler (const char *path)
 
   if (has_subdir)
     /* The user is trying to access a non-existent subdirectory of /proc. */
-    return FH_BAD;
+    return FH_NADA;
   else
     /* Return FH_PROC so that we can return EROFS if the user is trying to
        create a file. */
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 24704f4c1..71a31ac1a 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -76,7 +76,7 @@ static const virt_tab_t process_tab[] =
   { _VN ("uid"),        FH_PROCESS,   virt_file,      format_process_uid },
   { _VN ("winexename"), FH_PROCESS,   virt_file,      format_process_winexename },
   { _VN ("winpid"),     FH_PROCESS,   virt_file,      format_process_winpid },
-  { NULL, 0,	        FH_BAD,       virt_none,      NULL }
+  { NULL, 0,	        FH_NADA,       virt_none,      NULL }
 };
 
 static const int PROCESS_LINK_COUNT =
diff --git a/winsup/cygwin/fhandler_procnet.cc b/winsup/cygwin/fhandler_procnet.cc
index eede6f2c8..cda0a65dd 100644
--- a/winsup/cygwin/fhandler_procnet.cc
+++ b/winsup/cygwin/fhandler_procnet.cc
@@ -42,7 +42,7 @@ static const virt_tab_t procnet_tab[] =
   { _VN ("."),	      FH_PROCNET, virt_directory, NULL },
   { _VN (".."),       FH_PROCNET, virt_directory, NULL },
   { _VN ("if_inet6"), FH_PROCNET, virt_file,      format_procnet_ifinet6 },
-  { NULL, 0,	      FH_BAD,	  virt_none,      NULL }
+  { NULL, 0,	      FH_NADA,	  virt_none,      NULL }
 };
 
 static const int PROCNET_LINK_COUNT =
diff --git a/winsup/cygwin/fhandler_procsysvipc.cc b/winsup/cygwin/fhandler_procsysvipc.cc
index ec1e34807..581274895 100644
--- a/winsup/cygwin/fhandler_procsysvipc.cc
+++ b/winsup/cygwin/fhandler_procsysvipc.cc
@@ -49,7 +49,7 @@ static const virt_tab_t procsysvipc_tab[] =
   { _VN ("msg"),	FH_PROCSYSVIPC,   virt_file,   format_procsysvipc_msg },
   { _VN ("sem"),	FH_PROCSYSVIPC,   virt_file,   format_procsysvipc_sem },
   { _VN ("shm"),	FH_PROCSYSVIPC,   virt_file,   format_procsysvipc_shm },
-  { NULL, 0,		FH_BAD,		  virt_none,   NULL }
+  { NULL, 0,		FH_NADA,		  virt_none,   NULL }
 };
 
 static const int PROCSYSVIPC_LINK_COUNT =
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 0800cd936..821d6e94e 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -472,7 +472,7 @@ process_ioctl (void *)
 fhandler_tty_slave::fhandler_tty_slave (int unit)
   : fhandler_tty_common (), inuse (NULL)
 {
-  if (unit >= 0)
+  if (unit > 0)
     dev ().parse (DEV_TTYS_MAJOR, unit);
 }
 
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index 28a85fdf0..aac78cf89 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -620,7 +620,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
     {
       dev = *proc_dev;
       dev = fhandler_proc::get_proc_fhandler (src_path);
-      if (dev == FH_BAD)
+      if (dev == FH_NADA)
 	return ENOENT;
       set_flags (flags, PATH_BINARY);
       if (isprocsys_dev (dev))