Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/Makefile.in,v
retrieving revision 1.87
diff -u -3 -p -u -p -b -B -r1.87 Makefile.in
--- Makefile.in	18 May 2002 06:10:16 -0000	1.87
+++ Makefile.in	22 May 2002 16:00:06 -0000
@@ -122,9 +122,9 @@ DLL_OFILES:=assert.o autoload.o cygheap.
 	cygserver_transport_pipes.o cygserver_transport_sockets.o dcrt0.o debug.o \
 	delqueue.o dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \
 	exec.o external.o fcntl.o fhandler.o fhandler_clipboard.o fhandler_console.o \
-	fhandler_disk_file.o fhandler_dsp.o fhandler_floppy.o fhandler_mem.o \
-	fhandler_proc.o fhandler_process.o fhandler_random.o fhandler_raw.o \
-	fhandler_registry.o fhandler_serial.o fhandler_socket.o \
+	fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o fhandler_floppy.o \
+	fhandler_mem.o fhandler_proc.o fhandler_process.o fhandler_random.o \
+	fhandler_raw.o fhandler_registry.o fhandler_serial.o fhandler_socket.o \
 	fhandler_tape.o fhandler_termios.o fhandler_tty.o fhandler_virtual.o \
 	fhandler_windows.o fhandler_zero.o fnmatch.o fork.o glob.o grp.o \
 	heap.o init.o ioctl.o ipc.o localtime.o malloc.o miscfuncs.o mmap.o \
Index: dtable.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dtable.cc,v
retrieving revision 1.80
diff -u -3 -p -u -p -b -B -r1.80 dtable.cc
--- dtable.cc	3 May 2002 02:43:45 -0000	1.80
+++ dtable.cc	22 May 2002 16:00:09 -0000
@@ -374,6 +374,9 @@ dtable::build_fhandler (int fd, DWORD de
       case FH_PROCESS:
         fh = cnew (fhandler_process) ();
         break;
+      case FH_DEV:
+        fh = cnew (fhandler_dev) ();
+        break;
       default:
 	system_printf ("internal error -- unknown device - %p", dev);
 	fh = NULL;
Index: fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.115
diff -u -3 -p -u -p -b -B -r1.115 fhandler.h
--- fhandler.h	12 May 2002 03:08:59 -0000	1.115
+++ fhandler.h	22 May 2002 16:00:12 -0000
@@ -73,8 +73,9 @@ enum
   FH_PROC    = 0x0000001a,      /* /proc */
   FH_REGISTRY =0x0000001b,      /* /proc/registry */
   FH_PROCESS = 0x0000001c,      /* /proc/<n> */
+  FH_DEV     = 0x0000001d,      /* /dev */
 
-  FH_NDEV    = 0x0000001d,      /* Maximum number of devices */
+  FH_NDEV    = 0x0000001e,      /* Maximum number of devices */
   FH_DEVMASK = 0x00000fff,	/* devices live here */
   FH_BAD     = 0xffffffff
 };
@@ -103,8 +104,6 @@ enum
 extern const char *windows_device_names[];
 extern struct __cygwin_perfile *perfile_table;
 #define __fmode (*(user_data->fmode_ptr))
-extern const char proc[];
-extern const int proc_len;
 
 class select_record;
 class path_conv;
@@ -1113,10 +1112,20 @@ class fhandler_process: public fhandler_
   void fill_filebuf ();
 };
 
+class fhandler_dev: public fhandler_virtual
+{
+ public:
+  fhandler_dev ();
+  int exists(const char *path);
+  struct dirent *readdir (DIR *);
+  int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+};
+
 typedef union
 {
   char base[sizeof(fhandler_base)];
   char console[sizeof(fhandler_console)];
+  char dev[sizeof(fhandler_dev)];
   char dev_clipboard[sizeof(fhandler_dev_clipboard)];
   char dev_dsp[sizeof(fhandler_dev_dsp)];
   char dev_floppy[sizeof(fhandler_dev_floppy)];
Index: fhandler_proc.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_proc.cc,v
retrieving revision 1.4
diff -u -3 -p -u -p -b -B -r1.4 fhandler_proc.cc
--- fhandler_proc.cc	12 May 2002 01:37:48 -0000	1.4
+++ fhandler_proc.cc	22 May 2002 16:00:13 -0000
@@ -23,6 +23,7 @@ details. */
 #include "pinfo.h"
 #include "dtable.h"
 #include "cygheap.h"
+#include "shared_info.h"
 #include <assert.h>
 #include <sys/utsname.h>
 #include "ntdll.h"
@@ -67,10 +68,6 @@ static const DWORD proc_fhandlers[PROC_L
   FH_PROC
 };
 
-/* name of the /proc filesystem */
-const char proc[] = "/proc";
-const int proc_len = sizeof (proc) - 1;
-
 static off_t format_proc_meminfo (char *destbuf, size_t maxsize);
 static off_t format_proc_stat (char *destbuf, size_t maxsize);
 static off_t format_proc_uptime (char *destbuf, size_t maxsize);
@@ -83,7 +80,7 @@ DWORD
 fhandler_proc::get_proc_fhandler (const char *path)
 {
   debug_printf ("get_proc_fhandler(%s)", path);
-  path += proc_len;
+  path += mount_table->proc_len - 1;
   /* Since this method is called from path_conv::check we can't rely on
    * it being normalised and therefore the path may have runs of slashes
    * in it.
@@ -138,7 +135,7 @@ int
 fhandler_proc::exists (const char *path)
 {
   debug_printf ("exists (%s)", path);
-  path += proc_len;
+  path += mount_table->proc_len - 1;
   if (*path == 0)
     return 2;
   for (int i = 0; proc_listing[i]; i++)
@@ -162,7 +159,7 @@ fhandler_proc::fstat (struct __stat64 *b
 {
   debug_printf ("fstat (%s)", get_name ());
   const char *path = get_name ();
-  path += proc_len;
+  path += mount_table->proc_len - 1;
   (void) fhandler_base::fstat (buf, pc);
 
   buf->st_mode &= ~_IFMT & NO_W;
@@ -235,7 +232,7 @@ fhandler_proc::open (path_conv *pc, int 
 
   const char *path;
 
-  path = get_name () + proc_len;
+  path = get_name () + mount_table->proc_len - 1;
 
   if (!*path)
     {
Index: fhandler_process.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_process.cc,v
retrieving revision 1.5
diff -u -3 -p -u -p -b -B -r1.5 fhandler_process.cc
--- fhandler_process.cc	12 May 2002 01:37:48 -0000	1.5
+++ fhandler_process.cc	22 May 2002 16:00:18 -0000
@@ -77,7 +77,7 @@ int
 fhandler_process::exists (const char *path)
 {
   debug_printf ("exists (%s)", path);
-  path += proc_len + 1;
+  path += mount_table->proc_len;
   while (*path != 0 && !SLASH_P (*path))
     path++;
   if (*path == 0)
@@ -100,7 +100,7 @@ fhandler_process::fstat (struct __stat64
   const char *path = get_name ();
   int file_type = exists (path);
   (void) fhandler_base::fstat (buf, pc);
-  path += proc_len + 1;
+  path += mount_table->proc_len;
   int pid = atoi (path);
   winpids pids;
   _pinfo *p;
@@ -167,7 +167,7 @@ fhandler_process::open (path_conv *pc, i
     goto out;
 
   const char *path;
-  path = get_name () + proc_len + 1;
+  path = get_name () + mount_table->proc_len;
   pid = atoi (path);
   while (*path != 0 && !SLASH_P (*path))
     path++;
Index: fhandler_registry.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_registry.cc,v
retrieving revision 1.4
diff -u -3 -p -u -p -b -B -r1.4 fhandler_registry.cc
--- fhandler_registry.cc	12 May 2002 01:37:48 -0000	1.4
+++ fhandler_registry.cc	22 May 2002 16:00:19 -0000
@@ -22,6 +22,7 @@ details. */
 #include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
+#include "shared_info.h"
 #include <assert.h>
 
 #define _COMPILING_NEWLIB
@@ -103,7 +104,7 @@ fhandler_registry::exists (const char *p
   HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
 
   debug_printf ("exists (%s)", path);
-  path += proc_len + 1 + registry_len;
+  path += mount_table->proc_len + registry_len;
 
   while (SLASH_P (*path))
     path++;
@@ -216,7 +217,7 @@ fhandler_registry::readdir (DIR * dir)
   char buf[buf_size];
   HANDLE handle;
   struct dirent *res = NULL;
-  const char *path = dir->__d_dirname + proc_len + 1 + registry_len;
+  const char *path = dir->__d_dirname + mount_table->proc_len + registry_len;
   LONG error;
 
   if (*path == 0)
@@ -343,7 +344,7 @@ fhandler_registry::open (path_conv *pc, 
     goto out;
 
   const char *path;
-  path = get_name () + proc_len + 1 + registry_len;
+  path = get_name () + mount_table->proc_len + registry_len;
   if (!*path)
     {
       if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
Index: fhandler_virtual.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_virtual.cc,v
retrieving revision 1.5
diff -u -3 -p -u -p -b -B -r1.5 fhandler_virtual.cc
--- fhandler_virtual.cc	12 May 2002 01:59:53 -0000	1.5
+++ fhandler_virtual.cc	22 May 2002 16:00:19 -0000
@@ -159,7 +159,6 @@ fhandler_virtual::close ()
     cfree (filebuf);
   filebuf = NULL;
   bufalloc = (size_t) -1;
-  cygwin_shared->delqueue.process_queue ();
   return 0;
 }
 
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.207
diff -u -3 -p -u -p -b -B -r1.207 path.cc
--- path.cc	18 May 2002 20:27:49 -0000	1.207
+++ path.cc	22 May 2002 16:00:30 -0000
@@ -118,11 +118,15 @@ int pcheck_case = PCHECK_RELAXED; /* Det
    (isdirsep(path[mount_table->cygdrive_len + 1]) || \
     !path[mount_table->cygdrive_len + 1]))
 
+#define isdev(path) \
+  (path_prefix_p (mount_table->dev, (path), mount_table->dev_len))
+
 #define isproc(path) \
-  (path_prefix_p (proc, (path), proc_len))
+  (path_prefix_p (mount_table->proc, (path), mount_table->proc_len))
 
 #define isvirtual_dev(devn) \
-  (devn == FH_CYGDRIVE || devn == FH_PROC || devn == FH_REGISTRY || devn == FH_PROCESS)
+  (devn == FH_CYGDRIVE || devn == FH_PROC || devn == FH_REGISTRY || \
+   devn == FH_PROCESS || devn == FH_DEV)
 
 /* Return non-zero if PATH1 is a prefix of PATH2.
    Both are assumed to be of the same path style and / vs \ usage.
@@ -504,7 +508,7 @@ path_conv::check (const char *src, unsig
 	  if (error)
 	    return;
 
-	  if (devn == FH_CYGDRIVE)
+    if (devn == FH_CYGDRIVE || devn == FH_DEV)
 	    {
 	      if (!component)
 		fileattr = FILE_ATTRIBUTE_DIRECTORY;
@@ -1039,7 +1043,7 @@ get_device_number (const char *unix_path
   DWORD devn = FH_BAD;
   unit = 0;
 
-  if (*unix_path == '/' && udeveqn ("/dev/", 5))
+  if (*unix_path == '/' && udeveqn (mount_table->dev, 5))
     {
       devn = get_devn (unix_path, unit);
       if (devn == FH_BAD && *w32_path == '\\' && wdeveqn ("\\dev\\", 5))
@@ -1324,6 +1328,15 @@ mount_info::init ()
   /* Fetch the mount table and cygdrive-related information from
      the registry.  */
   from_registry ();
+
+  /* These paths are hard-coded because programs rely on them being at these
+     paths. */
+  strcpy(dev, "/dev");
+  slashify (dev, dev, 1);
+  dev_len = strlen(dev);
+  strcpy(proc, "/proc");
+  slashify (proc, proc, 1);
+  proc_len = strlen(proc);
 }
 
 /* conv_to_win32_path: Ensure src_path is a pure Win32 path and store
@@ -1439,6 +1452,18 @@ mount_info::conv_to_win32_path (const ch
       if (devn == FH_BAD)
         return ENOENT;
     }
+  else if (isdev (pathbuf))
+    {
+      int n = mount_table->dev_len - 1;
+      if (!pathbuf[n] ||
+         (pathbuf[n] == '/' && pathbuf[n + 1] == '.' && !pathbuf[n + 2]))
+        {
+          unit = 0;
+          dst[0] = '\0';
+          if (mount_table->dev_len > 1)
+             devn = FH_DEV;
+        }
+    }
   else if (iscygdrive (pathbuf))
     {
       int n = mount_table->cygdrive_len - 1;
Index: shared_info.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/shared_info.h,v
retrieving revision 1.19
diff -u -3 -p -u -p -b -B -r1.19 shared_info.h
--- shared_info.h	26 Dec 2001 21:35:16 -0000	1.19
+++ shared_info.h	22 May 2002 16:00:31 -0000
@@ -39,10 +39,10 @@ class mount_item
    scheme should be satisfactory for a long while yet.  */
 #define MAX_MOUNTS 30
 
-#define MOUNT_VERSION	27	// increment when mount table changes and
+#define MOUNT_VERSION 28  // increment when mount table changes and
 #define MOUNT_VERSION_MAGIC CYGWIN_VERSION_MAGIC (MOUNT_MAGIC, MOUNT_VERSION)
 #define CURR_MOUNT_MAGIC 0x41e0
-#define MOUNT_INFO_CB 16488
+#define MOUNT_INFO_CB 17016
 
 class reg_key;
 
@@ -64,6 +64,12 @@ class mount_info
   char cygdrive[MAX_PATH];
   size_t cygdrive_len;
   unsigned cygdrive_flags;
+  /* This is where /dev is mounted. */
+  char dev[MAX_PATH];
+  size_t dev_len;
+  /* This is where /proc is mounted. */
+  char proc[MAX_PATH];
+  size_t proc_len;
  private:
   int posix_sorted[MAX_MOUNTS];
   int native_sorted[MAX_MOUNTS];
--- /dev/null	Wed May 22 17:04:13 2002
+++ fhandler_dev.cc	Wed May 22 16:58:09 2002
@@ -0,0 +1,153 @@
+/* fhandler_dec.cc: fhandler for /dev virtual filesystem
+
+   Copyright 2002 Red Hat, Inc.
+
+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. */
+
+#include "winsup.h"
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/cygwin.h>
+#include "cygerrno.h"
+#include "security.h"
+#include "fhandler.h"
+#include "path.h"
+#include "sigproc.h"
+#include "pinfo.h"
+#include "dtable.h"
+#include "cygheap.h"
+#include "shared_info.h"
+#include <assert.h>
+
+#define _COMPILING_NEWLIB
+#include <dirent.h>
+
+static const int DEV_LINK_COUNT = 573;
+
+static const char *dev_listing[DEV_LINK_COUNT];
+
+static bool dev_listing_initialised = false;
+
+static void initialise_dev_listing ();
+
+/* Returns 0 if path doesn't exist, >0 if path is a directory,
+ * <0 if path is a file.
+ */
+int
+fhandler_dev::exists (const char *path)
+{
+  debug_printf ("exists (%s)", path);
+  path += mount_table->dev_len - 1;
+  if (*path == 0)
+    return 2;
+  return 0;
+}
+
+int
+fhandler_dev::fstat (struct __stat64 *buf, path_conv *pc)
+{
+      buf->st_nlink = DEV_LINK_COUNT;
+      buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+      return 0;
+}
+
+fhandler_dev::fhandler_dev ():
+  fhandler_virtual (FH_DEV)
+{
+        if (!dev_listing_initialised) {
+                initialise_dev_listing();
+                dev_listing_initialised = true;
+        }
+}
+
+struct dirent *
+fhandler_dev::readdir (DIR * dir)
+{
+  if (dir->__d_position >= DEV_LINK_COUNT)
+    return NULL;
+  strcpy (dir->__d_dirent->d_name, dev_listing[dir->__d_position++]);
+  syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
+                  dir->__d_dirent->d_name);
+  return dir->__d_dirent;
+}
+
+static
+void
+initialise_dev_listing()
+{
+        char *mem = (char *)malloc (5000), *device = mem;
+        int devn = 0;
+        for (int i = 0; i <= 127; i++) {
+                __small_sprintf (device, "st%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 127; i++) {
+                __small_sprintf (device, "nst%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 15; i++) {
+                __small_sprintf (device, "fd%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 15; i++) {
+                __small_sprintf (device, "scd%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 11; i++) {
+                for (int u = 0; u <= 15; u++) {
+                        if (u == 0)
+                                __small_sprintf (device, "sd%c", i+'a');
+                        else
+                                __small_sprintf (device, "sd%c%u", i+'a', u);
+                        dev_listing[devn++] = (const char *)device;
+                        device += strlen(device) + 1;
+                }
+        }
+        for (int i = 0; i <= 63; i++) {
+                __small_sprintf (device, "tty%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 3; i++) {
+                __small_sprintf (device, "ttyS%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        for (int i = 0; i <= 3; i++) {
+                __small_sprintf (device, "com%u", i);
+                dev_listing[devn++] = (const char *)device;
+                device += strlen(device) + 1;
+        }
+        dev_listing[devn++] = "tty";
+        dev_listing[devn++] = "ttym";
+        dev_listing[devn++] = "ptmx";
+        dev_listing[devn++] = "windows";
+        dev_listing[devn++] = "dsp";
+        dev_listing[devn++] = "conin";
+        dev_listing[devn++] = "conout";
+        dev_listing[devn++] = "null";
+        dev_listing[devn++] = "zero";
+        dev_listing[devn++] = "random";
+        dev_listing[devn++] = "urandom";
+        dev_listing[devn++] = "mem";
+        dev_listing[devn++] = "clipboard";
+        dev_listing[devn++] = "port";
+        dev_listing[devn++] = "pipe";
+        dev_listing[devn++] = "piper";
+        dev_listing[devn++] = "pipew";
+        dev_listing[devn++] = "tcp";
+        dev_listing[devn++] = "udp";
+        dev_listing[devn++] = "streamsocket";
+        dev_listing[devn++] = "dgsocket";
+        debug_printf ("%d bytes used, %d devices", device - mem, devn);
+  }
