Index: cygwin/path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.162
diff -u -p -r1.162 path.cc
--- path.cc	2001/09/07 21:32:04	1.162
+++ path.cc	2001/09/09 04:58:37
@@ -795,6 +795,106 @@ get_raw_device_number (const char *uxnam
   return devn;
 }
 
+DWORD
+mount_info::get_mount_device_number (const char *uxname)
+{
+  DWORD devn = FH_BAD;
+  mount_item *mi = NULL;        /* initialized to avoid compiler warning */
+  char pathbuf[MAX_PATH];
+
+  /* we normalise the path because ../ may take us out of a mount entry */
+  if (normalize_posix_path (uxname, pathbuf))
+    {
+      debug_printf ("FH_BAD = get_mount_device_number (%s)", uxname);
+      return FH_BAD;
+    }
+
+  int i, chrooted_path_len;
+  chrooted_path_len = 0;
+  /* Check the mount table for prefix matches. */
+  for (i = 0; i < nmounts; i++)
+    {
+      const char *path;
+      int len;
+      mi = mount + posix_sorted[i];
+      if (!cygheap->root.exists ()
+          || (mi->posix_pathlen == 1 && mi->posix_path[0] == '/'))
+        {
+          path = mi->posix_path;
+          len = mi->posix_pathlen;
+        }
+      else if (cygheap->root.posix_ok (mi->posix_path))
+        {
+          path = cygheap->root.unchroot (mi->posix_path);
+          chrooted_path_len = len = strlen (path);
+        }
+      else
+        {
+          chrooted_path_len = 0;
+          continue;
+        }
+      if (path_prefix_p (path, pathbuf, len))
+        break;
+    }
+
+  if (i >= nmounts)
+    {
+      /* do nothing */
+//      system_printf ("found root match %s\n", pathbuf);
+    }
+  else
+    {
+      /* found the device for the path */
+//      system_printf ("found match %s devn = %d\n", pathbuf, mi->devn);
+      #if 0
+      int n;
+      const char *native_path;
+      int posix_pathlen;
+      if (chroot_ok || chrooted_path_len || mi->posix_pathlen != 1
+          || mi->posix_path[0] != '/')
+        {
+          n = mi->native_pathlen;
+          native_path = mi->native_path;
+          posix_pathlen = chrooted_path_len ?: mi->posix_pathlen;
+          chroot_ok = 1;
+        }
+      else
+        {
+          n = cygheap->root.native_length ();
+          native_path = cygheap->root.native_path ();
+          posix_pathlen = mi->posix_pathlen;
+          chroot_ok = 1;
+        }
+      memcpy (dst, native_path, n + 1);
+      const char *p = pathbuf + posix_pathlen;
+      if (*p == '/')
+        /* nothing */;
+      else if ((isdrive (dst) && !dst[2]) || *p)
+        dst[n++] = '\\';
+        strcpy (dst + n, p);
+        backslashify (dst, dst, 0);
+        *flags = mi->flags;
+	#endif
+    }
+																	      
+
+  return devn;
+}
+
+const char *
+get_device_name (DWORD devn)
+{
+  switch (devn)
+    {
+    case FH_BAD:
+      return "Bad device number";
+    case FH_DEVFS:
+      return "DEVFS";
+    default:
+      return "UNKNOWN";
+    }
+}
+
 int __stdcall
 get_device_number (const char *name, int &unit, BOOL from_conv)
 {
@@ -869,6 +969,10 @@ get_device_number (const char *name, int
     devn = FH_SERIAL;
   else if (deveqn ("ttyS", 4) && (unit = digits (name + 4)) >= 0)
     devn = FH_SERIAL;
+  else if (deveq ("DEVFS"))
+    devn = FH_DEVFS;
+  else
+    devn = mount_table->get_mount_device_number (name);
 
   return devn;
 }
@@ -1505,7 +1609,7 @@ mount_info::set_flags_from_win32_path (c
 void
 mount_info::read_mounts (reg_key& r)
 {
-  char posix_path[MAX_PATH];
+  char posix_path[MAX_PATH], type[MAX_PATH];
   HKEY key = r.get_key ();
   DWORD i, posix_path_size;
   int res;
@@ -1539,10 +1643,12 @@ mount_info::read_mounts (reg_key& r)
 
       /* Fetch info from the subkey. */
       subkey.get_string ("native", native_path, sizeof (native_path), "");
+      subkey.get_string ("type", type, sizeof (type), "");
       mount_flags = subkey.get_int ("flags", 0);
 
       /* Add mount_item corresponding to registry mount point. */
-      res = mount_table->add_item (native_path, posix_path, mount_flags, FALSE);
+      res = mount_table->add_item (native_path, posix_path, type, mount_flags,
+      	FALSE);
       if (res && get_errno () == EMFILE)
 	break; /* The number of entries exceeds MAX_MOUNTS */
     }
@@ -1584,9 +1690,9 @@ mount_info::from_registry ()
 /* add_reg_mount: Add mount item to registry.  Return zero on success,
    non-zero on failure. */
 /* FIXME: Need a mutex to avoid collisions with other tasks. */
-
+/* We don't check the type parameter, to allow adding mounts for the next "boot" */
 int
-mount_info::add_reg_mount (const char * native_path, const char * posix_path, unsigned mountflags)
+mount_info::add_reg_mount (const char * native_path, const char * posix_path, const char *type, unsigned mountflags)
 {
   int res = 0;
 
@@ -1609,6 +1715,10 @@ mount_info::add_reg_mount (const char * 
       res = subkey.set_string ("native", native_path);
       if (res != ERROR_SUCCESS)
 	goto err;
+      system_printf("type is %s\n",type);
+      res = subkey.set_string ("type", type);
+      if (res != ERROR_SUCCESS)
+	goto err;
       res = subkey.set_int ("flags", mountflags);
     }
   else /* local_machine mount */
@@ -1632,6 +1742,11 @@ mount_info::add_reg_mount (const char * 
       res = subkey.set_string ("native", native_path);
       if (res != ERROR_SUCCESS)
 	goto err;
+      system_printf("type is %s\n",type);
+      res = subkey.set_string ("type", type);
+      if (res != ERROR_SUCCESS)
+        goto err;
+	    
       res = subkey.set_int ("flags", mountflags);
 
       sys_mount_table_counter++;
@@ -1947,15 +2062,18 @@ mount_info::sort ()
    do this when called internally, but it's cleaner to keep it all here.  */
 
 int
-mount_info::add_item (const char *native, const char *posix, unsigned mountflags, int reg_p)
+mount_info::add_item (const char *native, const char *posix, const char *type, unsigned mountflags, int reg_p)
 {
   /* Something's wrong if either path is NULL or empty, or if it's
      not a UNC or absolute path. */
 
+  int unit = 0;
+
   if ((native == NULL) || (*native == 0) ||
       (posix == NULL) || (*posix == 0) ||
       !isabspath (native) || !isabspath (posix) ||
-      slash_unc_prefix_p (posix) || isdrive (posix))
+      slash_unc_prefix_p (posix) || isdrive (posix) ||
+      type && type[0] && (DWORD) get_device_number (type, unit, FALSE) == FH_BAD)
     {
       set_errno (EINVAL);
       return -1;
@@ -1971,8 +2089,8 @@ mount_info::add_item (const char *native
   slashify (posix, posixtmp, 0);
   nofinalslash (posixtmp, posixtmp);
 
-  debug_printf ("%s[%s], %s[%s], %p",
-		native, nativetmp, posix, posixtmp, mountflags);
+  debug_printf ("%s[%s], %s[%s], %s, %p",
+		native, nativetmp, posix, posixtmp, type, mountflags);
 
   /* Duplicate /'s in path are an error. */
   for (char *p = posixtmp + 1; *p; ++p)
@@ -2000,12 +2118,12 @@ mount_info::add_item (const char *native
       return -1;
     }
 
-  if (reg_p && add_reg_mount (nativetmp, posixtmp, mountflags))
+  if (reg_p && add_reg_mount (nativetmp, posixtmp, type, mountflags))
     return -1;
 
   if (i == nmounts)
     nmounts++;
-  mount[i].init (nativetmp, posixtmp, mountflags);
+  mount[i].init (nativetmp, posixtmp, type, mountflags);
   sort ();
 
   return 0;
@@ -2109,7 +2227,7 @@ mount_info::read_v1_mounts (reg_key r, u
 	     we're reading. */
 	  mountflags |= which;
 
-	  int res = mount_table->add_item (win32path, unixpath, mountflags, TRUE);
+	  int res = mount_table->add_item (win32path, unixpath, NULL, mountflags, TRUE);
 	  if (res && get_errno () == EMFILE)
 	    break; /* The number of entries exceeds MAX_MOUNTS */
 	}
@@ -2149,7 +2267,7 @@ mount_info::import_v1_mounts ()
 /************************* mount_item class ****************************/
 
 static mntent *
-fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
+fillout_mntent (const char *native_path, const char *posix_path, DWORD type, unsigned flags)
 {
 #ifdef _MT_SAFE
   struct mntent &ret=_reent_winsup()->mntbuf;
@@ -2175,10 +2293,15 @@ fillout_mntent (const char *native_path,
   strcpy (_reent_winsup ()->mnt_dir, posix_path);
   ret.mnt_dir = _reent_winsup ()->mnt_dir;
 
-  if (!(flags & MOUNT_SYSTEM))		/* user mount */
-    strcpy (_reent_winsup ()->mnt_type, (char *) "user");
-  else					/* system mount */
-    strcpy (_reent_winsup ()->mnt_type, (char *) "system");
+  if (type == FH_BAD)
+    {
+      if (!(flags & MOUNT_SYSTEM))		/* user mount */
+        strcpy (_reent_winsup ()->mnt_type, (char *) "user");
+      else					/* system mount */
+        strcpy (_reent_winsup ()->mnt_type, (char *) "system");
+    }
+  else						/* real mount */
+    strcpy (_reent_winsup ()->mnt_type, (char *) get_device_name (type));
 
   ret.mnt_type = _reent_winsup ()->mnt_type;
 
@@ -2209,7 +2332,7 @@ fillout_mntent (const char *native_path,
 struct mntent *
 mount_item::getmntent ()
 {
-  return fillout_mntent (native_path, posix_path, flags);
+  return fillout_mntent (native_path, posix_path, devn, flags);
 }
 
 static struct mntent *
@@ -2235,7 +2358,7 @@ cygdrive_getmntent ()
 	}
       native_path[2] = '\0';
       __small_sprintf (posix_path, "%s%c", mount_table->cygdrive, drive);
-      ret = fillout_mntent (native_path, posix_path, mount_table->cygdrive_flags);
+      ret = fillout_mntent (native_path, posix_path, FH_BAD, mount_table->cygdrive_flags);
       break;
     }
 
@@ -2254,10 +2377,22 @@ mount_info::getmntent (int x)
 /* Fill in the fields of a mount table entry.  */
 
 void
-mount_item::init (const char *native, const char *posix, unsigned mountflags)
+mount_item::init (const char *native, const char *posix, const char *type,
+		  unsigned mountflags)
 {
   strcpy ((char *) native_path, native);
   strcpy ((char *) posix_path, posix);
+  if (type && type[0])
+    {
+      devn = get_device_number (type, unit, FALSE);
+      system_printf("mount entry has type %s devn %d\n", type, devn);
+    }
+  else
+    {
+      devn = FH_BAD; 
+      /* FH_BAD here forces dtable::build_fhandler to check for sockets etc */
+      unit = 0;
+    }
 
   native_pathlen = strlen (native_path);
   posix_pathlen = strlen (posix_path);
@@ -2276,7 +2411,7 @@ mount_item::init (const char *native, co
 
 extern "C"
 int
-mount (const char *win32_path, const char *posix_path, unsigned flags)
+mount (const char *win32_path, const char *posix_path, const char *type, unsigned flags)
 {
   int res = -1;
 
@@ -2289,7 +2424,7 @@ mount (const char *win32_path, const cha
       win32_path = NULL;
     }
   else
-    res = mount_table->add_item (win32_path, posix_path, flags, TRUE);
+    res = mount_table->add_item (win32_path, posix_path, type, flags, TRUE);
 
   syscall_printf ("%d = mount (%s, %s, %p)", res, win32_path, posix_path, flags);
   return res;
Index: cygwin/shared_info.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/shared_info.h,v
retrieving revision 1.12
diff -u -p -r1.12 shared_info.h
--- shared_info.h	2001/09/07 21:32:05	1.12
+++ shared_info.h	2001/09/09 04:58:37
@@ -27,9 +27,13 @@ class mount_item
   char posix_path[MAX_PATH];
   int posix_pathlen;
 
+  /* file handler for the mount - 0 means default */
+  DWORD devn;
+  int unit;
+
   unsigned flags;
 
-  void init (const char *dev, const char *path, unsigned flags);
+  void init (const char *dev, const char *path, const char *type, unsigned flags);
 
   struct mntent *getmntent ();
 };
@@ -67,12 +71,12 @@ class mount_info
   int had_to_create_mount_areas;
 
   void init ();
-  int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
+  int add_item (const char *dev, const char *path, const char *type, 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);
+		      const char * type, unsigned mountflags);
   int del_reg_mount (const char * posix_path, unsigned mountflags);
 
   unsigned set_flags_from_win32_path (const char *path);
@@ -88,6 +92,7 @@ class mount_info
 			 char* system_flags);
 
   void import_v1_mounts ();
+  DWORD get_mount_device_number (const char *uxname);
 
  private:
 
@@ -100,6 +105,7 @@ class mount_info
   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 read_cygdrive_info_from_registry ();
+
 };
 
 /******** Close-on-delete queue ********/
Index: cygwin/include/sys/mount.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/sys/mount.h,v
retrieving revision 1.5
diff -u -p -r1.5 mount.h
--- mount.h	2001/03/05 21:29:23	1.5
+++ mount.h	2001/09/09 04:58:38
@@ -27,7 +27,7 @@ enum
   MOUNT_MIXED	=	0x080,	/* reads are text, writes are binary */
 };
 
-int mount (const char *, const char *, unsigned __flags);
+int mount (const char *, const char *, const char *, unsigned __flags);
 int umount (const char *);
 int cygwin_umount (const char *__path, unsigned __flags);
 
Index: utils/mount.cc
===================================================================
RCS file: /cvs/src/src/winsup/utils/mount.cc,v
retrieving revision 1.17
diff -u -p -r1.17 mount.cc
--- mount.cc	2001/09/04 01:09:39	1.17
+++ mount.cc	2001/09/09 04:58:38
@@ -45,7 +45,7 @@ error (const char *path)
    is a non-existent Win32 path. */
 
 static void
-do_mount (const char *dev, const char *where, int flags)
+do_mount (const char *dev, const char *where, const char *type, int flags)
 {
   struct stat statbuf;
   char win32_path[MAX_PATH];
@@ -69,7 +69,7 @@ do_mount (const char *dev, const char *w
     }
 #endif
 
-  if (mount (dev, where, flags))
+  if (mount (dev, where, type, flags))
     error (where);
 
   if (statres == -1)
@@ -228,7 +228,7 @@ main (int argc, char **argv)
       mount_commands ();
       break;
     default:
-      if (optind != (argc - 1))
+      if (optind != (argc - 1) && optind != (argc - 2))
 	{
 	  if (optind >= argc)
 	    fprintf (stderr, "%s: not enough arguments\n", progname);
@@ -237,7 +237,7 @@ main (int argc, char **argv)
 	  usage ();
 	}
       if (force || !mount_already_exists (argv[optind + 1], flags))
-	do_mount (argv[optind], argv[optind + 1], flags);
+	do_mount (argv[optind], argv[optind + 1], argv[optind + 2], flags);
       else
 	{
 	  errno = EBUSY;
@@ -376,7 +376,7 @@ change_cygdrive_prefix (const char *new_
 {
   flags |= MOUNT_AUTO;
 
-  if (mount (NULL, new_prefix, flags))
+  if (mount (NULL, new_prefix, NULL, flags))
     error (new_prefix);
 
   exit (0);
