diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 869196956..da7eb81bf 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,29 @@ +2009-05-13 Corinna Vinschen + Christopher Faylor + + * mount.cc (mount_info::got_usr_bin): Define. + (mount_info::got_usr_lib): Ditto. + (mount_info::root_idx): Ditto. + (mount_info::create_root_entry): Create root entry as immutable and + flag as automatic. + (mount_info::init): Remove "Huh? No /etc/fstab..." warning. + Unconditionally call from_fstab for user and system tables. Fill in + /usr/bin and /usr/lib if they have not been specified in /etc/fstab. + (oopts): Alphabetize. Add "override" option to allow overriding + immutable mount points. + (mount_info::add_item): Accommodate new MOUNT_IMMUTABLE flag intended + for root mount. + (mount_info::add_item): Detect "/usr/bin", "/usr/lib", and "/" and set + appropriate global state. + (fillout_mntent): Add ,auto to mount points added by Cygwin DLL. + (mount): Remove masking of MOUNT_SYSTEM. Allow user to shoot + themselves. Add comment. + * mount.h (mount_info::got_usr_bin): Declare. + (mount_info::got_usr_lib): Ditto. + (mount_info::root_idx): Ditto. + * include/sys/mount.h: Reformat enum. + Add MOUNT_{OVERRIDE,IMMUTABLE,AUTOMATIC}. + 2009-05-13 Corinna Vinschen * cygheap.h (cwdstuff): Convert to class. Make posix and dir private. diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h index 45b421e7d..f6e6ac64d 100644 --- a/winsup/cygwin/include/sys/mount.h +++ b/winsup/cygwin/include/sys/mount.h @@ -17,21 +17,26 @@ extern "C" { enum { - MOUNT_SYMLINK = 0x0001, /* "mount point" is a symlink */ - MOUNT_BINARY = 0x0002, /* "binary" format read/writes */ - MOUNT_SYSTEM = 0x0008, /* mount point came from system table */ - MOUNT_EXEC = 0x0010, /* Any file in the mounted directory gets 'x' bit */ - MOUNT_CYGDRIVE = 0x0020, /* mount point refers to cygdrive device mount */ - MOUNT_CYGWIN_EXEC = 0x0040, /* file or directory is or contains a cygwin - executable */ - MOUNT_MIXED = 0x0080, /* reads are text, writes are binary - not yet implemented */ - MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */ - MOUNT_DEVFS = 0x0200, /* /device "filesystem" */ - MOUNT_PROC = 0x0400, /* /proc "filesystem" */ - MOUNT_RO = 0x1000, /* read-only "filesystem" */ - MOUNT_NOACL = 0x2000, /* support reading/writing ACLs */ - MOUNT_NOPOSIX = 0x4000 /* Case insensitve path handling */ + MOUNT_SYMLINK = 0x00001, /* "mount point" is a symlink */ + MOUNT_BINARY = 0x00002, /* "binary" format read/writes */ + MOUNT_SYSTEM = 0x00008, /* mount point came from system table */ + MOUNT_EXEC = 0x00010, /* Any file in the mounted directory + gets 'x' bit */ + MOUNT_CYGDRIVE = 0x00020, /* mount point refers to cygdrive + device mount */ + MOUNT_CYGWIN_EXEC = 0x00040, /* file or directory is or contains a + cygwin executable */ + MOUNT_MIXED = 0x00080, /* reads are text, writes are binary + not yet implemented */ + MOUNT_NOTEXEC = 0x00100, /* don't check files for executable magic */ + MOUNT_DEVFS = 0x00200, /* /device "filesystem" */ + MOUNT_PROC = 0x00400, /* /proc "filesystem" */ + MOUNT_RO = 0x01000, /* read-only "filesystem" */ + MOUNT_NOACL = 0x02000, /* support reading/writing ACLs */ + MOUNT_NOPOSIX = 0x04000, /* Case insensitve path handling */ + MOUNT_OVERRIDE = 0x08000, /* Allow overriding of root */ + MOUNT_IMMUTABLE = 0x10000, /* Mount point can't be changed */ + MOUNT_AUTOMATIC = 0x20000 /* Mount point was added automatically */ }; int mount (const char *, const char *, unsigned __flags); diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index e5af613a1..9bc1896f9 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -31,6 +31,7 @@ details. */ #include #include #include +#include /* Determine if path prefix matches current cygdrive */ #define iscygdrive(path) \ @@ -44,6 +45,10 @@ details. */ #define isproc(path) \ (path_prefix_p (proc, (path), proc_len, false)) +bool mount_info::got_usr_bin; +bool mount_info::got_usr_lib; +int mount_info::root_idx = -1; + /* is_unc_share: Return non-zero if PATH begins with //server/share or with one of the native prefixes //./ or //?/ This function is only used to test for valid input strings. @@ -298,10 +303,12 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) inline void mount_info::create_root_entry (const PWCHAR root) { - /* Create a default root dir from the path the Cygwin DLL is in. */ + /* Create a default root dir derived from the location of the Cygwin DLL. + The entry is immutable, unless the "override" option is given in /etc/fstab. */ char native_root[PATH_MAX]; sys_wcstombs (native_root, PATH_MAX, root); - mount_table->add_item (native_root, "/", MOUNT_SYSTEM | MOUNT_BINARY); + mount_table->add_item (native_root, "/", + MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_OVERRIDE | MOUNT_AUTOMATIC); /* Create a default cygdrive entry. Note that this is a user entry. This allows to override it with mount, unless the sysadmin created a cygdrive entry in /etc/fstab. */ @@ -322,12 +329,28 @@ mount_info::init () pathend = wcpcpy (path, cygwin_shared->installation_root); create_root_entry (path); pathend = wcpcpy (pathend, L"\\etc\\fstab"); - if (from_fstab (false, path, pathend) /* The single | is correct! */ - | from_fstab (true, path, pathend)) - return; - /* FIXME: Remove warning message before releasing 1.7.0. */ - small_printf ("Huh? No /etc/fstab file in %W? Using default root and cygdrive prefix...\n", path); + from_fstab (false, path, pathend); + from_fstab (true, path, pathend); + + if (!got_usr_bin || !got_usr_lib) + { + char native[PATH_MAX]; + assert (root_idx != -1); + char *p = stpcpy (native, mount[root_idx].native_path); + if (!got_usr_bin) + { + stpcpy (p, "\\bin"); + mount_table->add_item (native, "/usr/bin", + MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC | MOUNT_CYGWIN_EXEC); + } + if (!got_usr_lib) + { + stpcpy (p, "\\lib"); + mount_table->add_item (native, "/usr/lib", + MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC); + } + } } static void @@ -835,18 +858,19 @@ struct opt bool clear; } oopts[] = { - {"user", MOUNT_SYSTEM, 1}, - {"nouser", MOUNT_SYSTEM, 0}, - {"binary", MOUNT_BINARY, 0}, - {"text", MOUNT_BINARY, 1}, - {"exec", MOUNT_EXEC, 0}, - {"notexec", MOUNT_NOTEXEC, 0}, - {"cygexec", MOUNT_CYGWIN_EXEC, 0}, - {"nosuid", 0, 0}, {"acl", MOUNT_NOACL, 1}, + {"binary", MOUNT_BINARY, 0}, + {"cygexec", MOUNT_CYGWIN_EXEC, 0}, + {"exec", MOUNT_EXEC, 0}, {"noacl", MOUNT_NOACL, 0}, + {"nosuid", 0, 0}, + {"notexec", MOUNT_NOTEXEC, 0}, + {"nouser", MOUNT_SYSTEM, 0}, + {"override", MOUNT_OVERRIDE, 0}, + {"posix=0", MOUNT_NOPOSIX, 0}, {"posix=1", MOUNT_NOPOSIX, 1}, - {"posix=0", MOUNT_NOPOSIX, 0} + {"text", MOUNT_BINARY, 1}, + {"user", MOUNT_SYSTEM, 1} }; static bool @@ -1054,7 +1078,7 @@ mount_info::write_cygdrive_info (const char *cygdrive_prefix, unsigned flags) set_errno (EINVAL); return -1; } - /* Don't allow to override a system cygdrive prefix. */ + /* Don't allow overriding of a system cygdrive prefix. */ if (cygdrive_flags & MOUNT_SYSTEM) { set_errno (EPERM); @@ -1238,14 +1262,26 @@ mount_info::add_item (const char *native, const char *posix, { if (!strcmp (mount[i].posix_path, posixtmp)) { - /* Don't allow to override a system mount with a user mount. */ + /* Don't allow overriding of a system mount with a user mount. */ if ((mount[i].flags & MOUNT_SYSTEM) && !(mountflags & MOUNT_SYSTEM)) { set_errno (EPERM); return -1; } - if ((mount[i].flags & MOUNT_SYSTEM) == (mountflags & MOUNT_SYSTEM)) + if ((mount[i].flags & MOUNT_SYSTEM) != (mountflags & MOUNT_SYSTEM)) + continue; + else if (!(mount[i].flags & MOUNT_IMMUTABLE)) break; + else if (mountflags & MOUNT_OVERRIDE) + { + mountflags |= MOUNT_IMMUTABLE; + break; + } + else + { + set_errno (EPERM); + return -1; + } } } @@ -1257,6 +1293,16 @@ mount_info::add_item (const char *native, const char *posix, if (i == nmounts) nmounts++; + + if (strcmp (posixtmp, "/usr/bin") == 0) + got_usr_bin = true; + + if (strcmp (posixtmp, "/usr/lib") == 0) + got_usr_lib = true; + + if (posixtmp[0] == '/' && posixtmp[1] == '\0') + root_idx = i; + mount[i].init (nativetmp, posixtmp, mountflags); sort (); @@ -1301,8 +1347,8 @@ mount_info::del_item (const char *path, unsigned flags) ? !strcmp (mount[ent].posix_path, pathtmp) : strcasematch (mount[ent].native_path, pathtmp))) { - /* Don't allow to remove a system mount. */ - if ((mount[ent].flags & MOUNT_SYSTEM)) + /* Don't allow removal of a system mount. */ + if (mount[ent].flags & MOUNT_SYSTEM) { set_errno (EPERM); return -1; @@ -1407,9 +1453,12 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags) if (!(flags & MOUNT_SYSTEM)) /* user mount */ strcat (_my_tls.locals.mnt_opts, (char *) ",user"); - if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */ + if (flags & MOUNT_CYGDRIVE) /* cygdrive */ strcat (_my_tls.locals.mnt_opts, (char *) ",noumount"); + if (flags & (MOUNT_AUTOMATIC | MOUNT_CYGDRIVE)) + strcat (_my_tls.locals.mnt_opts, (char *) ",auto"); + ret.mnt_opts = _my_tls.locals.mnt_opts; ret.mnt_freq = 1; @@ -1487,8 +1536,9 @@ mount_item::init (const char *native, const char *posix, unsigned mountflags) extern "C" int mount (const char *win32_path, const char *posix_path, unsigned flags) { + /* FIXME: Should we disallow setting MOUNT_SYSTEM in flags since it + isn't really supported except from fstab? */ int res = -1; - flags &= ~MOUNT_SYSTEM; myfault efault; if (efault.faulted (EFAULT)) diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index e03fd2e20..dcb456aec 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -104,6 +104,10 @@ class mount_info int nmounts; mount_item mount[MAX_MOUNTS]; + static bool got_usr_bin; + static bool got_usr_lib; + static int root_idx; + /* 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. */ diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index 86ca7d75b..dfa5e4d34 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,9 @@ +2009-05-13 Corinna Vinschen + Christopher Faylor + + * pathnames.sgml (mount-table): Sort mount options and add override + option. Add description of root mount handling. + 2009-05-13 Corinna Vinschen * pathnames.sgml (pathnames-unusual): Talk about using UTF-8 in C diff --git a/winsup/doc/pathnames.sgml b/winsup/doc/pathnames.sgml index 0a9766c6a..86b537b7e 100644 --- a/winsup/doc/pathnames.sgml +++ b/winsup/doc/pathnames.sgml @@ -67,25 +67,26 @@ options are binary, text, nouser, user, exec, notexec, cygexec, nosuid, posix=[0|1]. The meaning of the options is as follows. - acl - Cygwin uses the filesystem's access control lists (ACLs) to - implement real POSIX permissions (default). This flag only - affects filesystems supporting ACLs (NTFS) and is ignored - otherwise. - noacl - Cygwin ignores filesystem ACLs and only fakes a subset of - permission bits based on the DOS readonly attribute. This - behaviour is the default on FAT and FAT32. The flag is - ignored on NFS filesystems. - binary - Files default to binary mode (default). - text - Files default to CRLF text mode line endings. - nouser - Mount is a system-wide mount. - user - Mount is a user mount. - exec - Treat all files below mount point as executable. - notexec - Treat all files below mount point as not executable. - cygexec - Treat all files below mount point as cygwin executables. - nosuid - No suid files are allowed (currently unimplemented). - posix=0 - Switch off case sensitivity for paths under this mount point. - posix=1 - Switch on case sensitivity for paths under this mount point - (default). + acl - Cygwin uses the filesystem's access control lists (ACLs) to + implement real POSIX permissions (default). This flag only + affects filesystems supporting ACLs (NTFS) and is ignored + otherwise. + binary - Files default to binary mode (default). + cygexec - Treat all files below mount point as cygwin executables. + exec - Treat all files below mount point as executable. + noacl - Cygwin ignores filesystem ACLs and only fakes a subset of + permission bits based on the DOS readonly attribute. This + behaviour is the default on FAT and FAT32. The flag is + ignored on NFS filesystems. + nosuid - No suid files are allowed (currently unimplemented). + notexec - Treat all files below mount point as not executable. + nouser - Mount is a system-wide mount. + override - Force the override of an immutable mount point (currently "/"). + posix=0 - Switch off case sensitivity for paths under this mount point. + posix=1 - Switch on case sensitivity for paths under this mount point + (default). + text - Files default to CRLF text mode line endings. + user - Mount is a user mount. While normally the execute permission bits are used to evaluate @@ -105,8 +106,16 @@ overhead of opening each file to check for a '#!'. The but also prevents Cygwin from setting up commands and environment variables for a normal Windows program, adding another small performance gain. The opposite of these options is the notexec option, which -means that no files should be marked as executable under that mount point. - +means that no files should be marked as executable under that mount point. +A correct root directory is quite essential to the operation of +Cygwin. A default root directory is evaluated at startup so a +fstab entry for the root directory is not necessary. +If it's wrong, nothing will work as expected. Therefore, the root directory +evaluated by Cygwin itself is treated as an immutable mount point and can't +be overridden in /etc/fstab... unless you think you really know what you're +doing. In this case, use the override flag in the options +field in the /etc/fstab file. Since this is a dangerous +thing to do, do so at your own risk. nouser mount points are not overridable by a later call to mount. diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index cb29eee31..7024e29f3 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,12 @@ +2009-05-13 Corinna Vinschen + Christopher Faylor + + * mount.cc (oopts): Sort. Add override option. Add dummy "auto" + option for consistency. + (mount_entries): Avoid adding auto-mounted entries to -m output. + + * utils.sgml: Sort mount options. Add description of override option. + 2009-05-11 Corinna Vinschen * Makefile.in: Link ps.exe agains ntdll.dll. diff --git a/winsup/utils/mount.cc b/winsup/utils/mount.cc index fd2d6c539..a7903946c 100644 --- a/winsup/utils/mount.cc +++ b/winsup/utils/mount.cc @@ -1,7 +1,7 @@ /* mount.cc Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, - 2008 Red Hat, Inc. + 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -132,16 +132,19 @@ struct opt bool clear; } oopts[] = { - {"binary", MOUNT_BINARY, false}, - {"text", MOUNT_BINARY, true}, - {"exec", MOUNT_EXEC, false}, - {"notexec", MOUNT_NOTEXEC, false}, - {"cygexec", MOUNT_CYGWIN_EXEC, false}, - {"nosuid", 0, 0}, {"acl", MOUNT_NOACL, true}, + {"auto", 0, false}, + {"binary", MOUNT_BINARY, false}, + {"cygexec", MOUNT_CYGWIN_EXEC, false}, + {"exec", MOUNT_EXEC, false}, {"noacl", MOUNT_NOACL, false}, - {"posix=1", MOUNT_NOPOSIX, true}, + {"nosuid", 0, false}, + {"notexec", MOUNT_NOTEXEC, false}, + {"override", MOUNT_OVERRIDE, true}, {"posix=0", MOUNT_NOPOSIX, false}, + {"posix=1", MOUNT_NOPOSIX, true}, + {"text", MOUNT_BINARY, true}, + {"user", MOUNT_SYSTEM, true} }; static void @@ -366,7 +369,7 @@ mount_entries (void) // write fstab entries for normal mount points while ((p = getmntent (m)) != NULL) // Only list non-cygdrives - if (!strstr (p->mnt_opts, ",noumount")) + if (!strstr (p->mnt_opts, ",noumount") && !strstr (p->mnt_opts, ",auto")) { char fsname[NT_MAX_PATH], dirname[NT_MAX_PATH]; printf (format_mnt, convert_spaces (fsname, p->mnt_fsname), diff --git a/winsup/utils/utils.sgml b/winsup/utils/utils.sgml index e78aa120d..751557700 100644 --- a/winsup/utils/utils.sgml +++ b/winsup/utils/utils.sgml @@ -786,16 +786,17 @@ most of the options are duplicates of other mount flags): acl - Use the filesystem's access control lists (ACLs) to implement real POSIX permissions (default). - noacl - Ignore ACLs and fake POSIX permissions. binary - Files default to binary mode (default). - text - Files default to CRLF text mode line endings. - exec - Treat all files below mount point as executable. - notexec - Treat all files below mount point as not executable. cygexec - Treat all files below mount point as cygwin executables. + exec - Treat all files below mount point as executable. + noacl - Ignore ACLs and fake POSIX permissions. nosuid - No suid files are allowed (currently unimplemented) + notexec - Treat all files below mount point as not executable. + override - Override immutable mount points. posix=0 - Switch off case sensitivity for paths under this mount point. posix=1 - Switch on case sensitivity for paths under this mount point (default). + text - Files default to CRLF text mode line endings. For a more complete description of the mount options and the