summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/include/sys/mount.h35
-rw-r--r--winsup/cygwin/mount.cc94
-rw-r--r--winsup/cygwin/mount.h4
4 files changed, 122 insertions, 37 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 869196956..da7eb81bf 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,4 +1,30 @@
2009-05-13 Corinna Vinschen <corinna@vinschen.de>
+ Christopher Faylor <me+cygwin@cgf.cx>
+
+ * 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 <corinna@vinschen.de>
* cygheap.h (cwdstuff): Convert to class. Make posix and dir private.
(cwdstuff::get_posix): New method.
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 <ntdll.h>
#include <wchar.h>
#include <stdio.h>
+#include <assert.h>
/* 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},
+ {"acl", MOUNT_NOACL, 1},
{"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},
+ {"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. */