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);