420 lines
14 KiB
Diff
420 lines
14 KiB
Diff
From d91f339f2f69d83e8662ef2336504f226d488100 Mon Sep 17 00:00:00 2001
|
|
From: Alexpux <alexey.pawlow@gmail.com>
|
|
Date: Thu, 12 Mar 2015 14:09:29 +0300
|
|
Subject: [PATCH 05/23] - Move root to /usr. - Change sorting mount points. -
|
|
Do not show warnings for DOS paths. - By default mount without ACLs. - Can
|
|
read /etc/fstab with short mount point format.
|
|
|
|
---
|
|
winsup/cygwin/cygheap.cc | 12 ++-
|
|
winsup/cygwin/globals.cc | 2 +-
|
|
winsup/cygwin/mount.cc | 189 ++++++++++++++++++++++++++++++++++++++++-------
|
|
winsup/cygwin/mount.h | 3 +-
|
|
winsup/cygwin/uinfo.cc | 2 +-
|
|
5 files changed, 177 insertions(+), 31 deletions(-)
|
|
|
|
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
|
|
index 87a5eb964..d6dc063e5 100644
|
|
--- a/winsup/cygwin/cygheap.cc
|
|
+++ b/winsup/cygwin/cygheap.cc
|
|
@@ -178,14 +178,22 @@ init_cygheap::init_installation_root ()
|
|
|
|
/* Strip off last path component ("\\cygwin1.dll") */
|
|
PWCHAR w = wcsrchr (installation_root, L'\\');
|
|
+#ifdef __MSYS__
|
|
+ /* Back two folders to get root as we have all stuff in usr subfolder */
|
|
+ for (int i=1; i >=0; --i)
|
|
+ {
|
|
+#endif
|
|
if (w)
|
|
{
|
|
*w = L'\0';
|
|
w = wcsrchr (installation_root, L'\\');
|
|
}
|
|
if (!w)
|
|
- api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
|
+ api_fatal ("Can't initialize MSYS2 installation root dir.\n"
|
|
"Invalid DLL path");
|
|
+#ifdef __MSYS__
|
|
+ }
|
|
+#endif
|
|
|
|
/* Copy result into installation_dir before stripping off "bin" dir and
|
|
revert to Win32 path. This path is added to the Windows environment
|
|
@@ -208,6 +216,7 @@ init_cygheap::init_installation_root ()
|
|
if (w > p)
|
|
*w = L'\0';
|
|
|
|
+#ifndef __MSYS__
|
|
for (int i = 1; i >= 0; --i)
|
|
{
|
|
reg_key r (i, KEY_WRITE, _WIDE (CYGWIN_INFO_INSTALLATIONS_NAME),
|
|
@@ -216,6 +225,7 @@ init_cygheap::init_installation_root ()
|
|
installation_root)))
|
|
break;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
void __stdcall
|
|
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
|
|
index 5c5d64ee4..34555e9d2 100644
|
|
--- a/winsup/cygwin/globals.cc
|
|
+++ b/winsup/cygwin/globals.cc
|
|
@@ -65,7 +65,7 @@ int NO_COPY dynamically_loaded;
|
|
|
|
/* Some CYGWIN environment variable variables. */
|
|
bool allow_glob = true;
|
|
-bool dos_file_warning;
|
|
+bool dos_file_warning = false;
|
|
bool ignore_case_with_glob;
|
|
bool pipe_byte;
|
|
bool reset_com;
|
|
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
|
|
index 4de65b23c..fa999c21d 100644
|
|
--- a/winsup/cygwin/mount.cc
|
|
+++ b/winsup/cygwin/mount.cc
|
|
@@ -39,7 +39,6 @@ details. */
|
|
(path_prefix_p (proc, (path), proc_len, false))
|
|
|
|
bool NO_COPY mount_info::got_usr_bin;
|
|
-bool NO_COPY mount_info::got_usr_lib;
|
|
int NO_COPY mount_info::root_idx = -1;
|
|
|
|
/* is_unc_share: Return non-zero if PATH begins with //server/share
|
|
@@ -331,7 +330,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|
#define MINIMAL_WIN_NTFS_FLAGS (FILE_CASE_SENSITIVE_SEARCH \
|
|
| FILE_CASE_PRESERVED_NAMES \
|
|
| FILE_UNICODE_ON_DISK \
|
|
- | FILE_PERSISTENT_ACLS \
|
|
| FILE_FILE_COMPRESSION \
|
|
| FILE_VOLUME_QUOTAS \
|
|
| FILE_SUPPORTS_SPARSE_FILES \
|
|
@@ -467,13 +465,13 @@ mount_info::create_root_entry (const PWCHAR root)
|
|
sys_wcstombs (native_root, PATH_MAX, root);
|
|
assert (*native_root != '\0');
|
|
if (add_item (native_root, "/",
|
|
- MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC)
|
|
+ MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC | MOUNT_NOACL)
|
|
< 0)
|
|
api_fatal ("add_item (\"%s\", \"/\", ...) failed, errno %d", native_root, errno);
|
|
/* 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. */
|
|
- cygdrive_flags = MOUNT_BINARY | MOUNT_NOPOSIX | MOUNT_CYGDRIVE;
|
|
+ cygdrive_flags = MOUNT_BINARY | MOUNT_NOPOSIX | MOUNT_CYGDRIVE | MOUNT_NOACL;
|
|
strcpy (cygdrive, CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX "/");
|
|
cygdrive_len = strlen (cygdrive);
|
|
}
|
|
@@ -493,25 +491,17 @@ mount_info::init (bool user_init)
|
|
pathend = wcpcpy (pathend, L"\\etc\\fstab");
|
|
from_fstab (user_init, path, pathend);
|
|
|
|
- if (!user_init && (!got_usr_bin || !got_usr_lib))
|
|
+
|
|
+ if (!user_init && !got_usr_bin)
|
|
{
|
|
char native[PATH_MAX];
|
|
if (root_idx < 0)
|
|
- api_fatal ("root_idx %d, user_shared magic %y, nmounts %d", root_idx, user_shared->version, nmounts);
|
|
+ api_fatal ("root_idx %d, user_shared magic %y, nmounts %d", root_idx, user_shared->version, nmounts);
|
|
char *p = stpcpy (native, mount[root_idx].native_path);
|
|
- if (!got_usr_bin)
|
|
- {
|
|
- stpcpy (p, "\\bin");
|
|
- add_item (native, "/usr/bin",
|
|
- MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC);
|
|
- }
|
|
- if (!got_usr_lib)
|
|
- {
|
|
- stpcpy (p, "\\lib");
|
|
- add_item (native, "/usr/lib",
|
|
- MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC);
|
|
- }
|
|
- }
|
|
+ stpcpy (p, "\\usr\\bin");
|
|
+ add_item (native, "/bin",
|
|
+ MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC | MOUNT_NOACL);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -607,6 +597,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|
/* See if this is a cygwin "device" */
|
|
if (win32_device_name (src_path, dst, dev))
|
|
{
|
|
+ debug_printf ("win32_device_name (%s)", src_path);
|
|
*flags = MOUNT_BINARY; /* FIXME: Is this a sensible default for devices? */
|
|
rc = 0;
|
|
goto out_no_chroot_check;
|
|
@@ -637,6 +628,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|
}
|
|
if (isproc (src_path))
|
|
{
|
|
+ debug_printf ("isproc (%s)", src_path);
|
|
dev = *proc_dev;
|
|
dev = fhandler_proc::get_proc_fhandler (src_path);
|
|
if (dev == FH_NADA)
|
|
@@ -658,6 +650,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|
off the prefix and transform it into an MS-DOS path. */
|
|
else if (iscygdrive (src_path))
|
|
{
|
|
+ debug_printf ("iscygdrive (%s) mount_table->cygdrive %s", src_path, mount_table->cygdrive);
|
|
int n = mount_table->cygdrive_len - 1;
|
|
int unit;
|
|
|
|
@@ -669,11 +662,15 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|
}
|
|
else if (cygdrive_win32_path (src_path, dst, unit))
|
|
{
|
|
+ debug_printf ("cygdrive_win32_path (%s)", src_path);
|
|
set_flags (flags, (unsigned) cygdrive_flags);
|
|
goto out;
|
|
}
|
|
else if (mount_table->cygdrive_len > 1)
|
|
+ {
|
|
+ debug_printf ("mount_table->cygdrive_len > 1 (%s)", src_path);
|
|
return ENOENT;
|
|
+ }
|
|
}
|
|
|
|
int chroot_pathlen;
|
|
@@ -684,7 +681,9 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|
const char *path;
|
|
int len;
|
|
|
|
- mi = mount + posix_sorted[i];
|
|
+ mi = mount + shortest_native_sorted[i];
|
|
+ debug_printf (" mount[%d] .. checking %s -> %s ", i, mi->posix_path, mi->native_path);
|
|
+
|
|
if (!cygheap->root.exists ()
|
|
|| (mi->posix_pathlen == 1 && mi->posix_path[0] == '/'))
|
|
{
|
|
@@ -915,7 +914,8 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
|
int pathbuflen = tail - pathbuf;
|
|
for (int i = 0; i < nmounts; ++i)
|
|
{
|
|
- mount_item &mi = mount[native_sorted[i]];
|
|
+ mount_item &mi = mount[longest_posix_sorted[i]];
|
|
+ debug_printf (" mount[%d] .. checking %s -> %s ", i, mi.posix_path, mi.native_path);
|
|
if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen,
|
|
mi.flags & MOUNT_NOPOSIX))
|
|
continue;
|
|
@@ -1143,8 +1143,17 @@ mount_info::from_fstab_line (char *line, bool user)
|
|
if (!*c)
|
|
return true;
|
|
cend = find_ws (c);
|
|
- *cend = '\0';
|
|
posix_path = conv_fstab_spaces (c);
|
|
+ if (!*cend)
|
|
+ {
|
|
+ unsigned mount_flags = MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_NOPOSIX | MOUNT_NOACL;
|
|
+
|
|
+ int res = mount_table->add_item (native_path, posix_path, mount_flags);
|
|
+ if (res && get_errno () == EMFILE)
|
|
+ return false;
|
|
+ return true;
|
|
+ }
|
|
+ *cend = '\0';
|
|
/* Third field: FS type. */
|
|
c = skip_ws (cend + 1);
|
|
if (!*c)
|
|
@@ -1373,16 +1382,145 @@ sort_by_native_name (const void *a, const void *b)
|
|
return res;
|
|
}
|
|
|
|
+/* sort_by_longest_posix_name: qsort callback to sort the mount entries.
|
|
+ Sort user mounts ahead of system mounts to the same POSIX path. */
|
|
+/* FIXME: should the user should be able to choose whether to
|
|
+ prefer user or system mounts??? */
|
|
+static int
|
|
+sort_by_longest_posix_name (const void *a, const void *b)
|
|
+{
|
|
+ mount_item *ap = mounts_for_sort + (*((int*) a));
|
|
+ mount_item *bp = mounts_for_sort + (*((int*) b));
|
|
+
|
|
+ /* Base weighting on the conversion that would give the longest
|
|
+ posix path. */
|
|
+ ssize_t alen = (ssize_t) strlen (ap->posix_path) - (ssize_t) strlen (ap->native_path);
|
|
+ ssize_t blen = (ssize_t) strlen (bp->posix_path) - (ssize_t) strlen (bp->native_path);
|
|
+
|
|
+ int res = blen - alen;
|
|
+
|
|
+ if (res)
|
|
+ return res; /* Path lengths differed */
|
|
+
|
|
+ /* The two paths were the same length, so just determine normal
|
|
+ lexical sorted order. */
|
|
+ res = strcmp (ap->posix_path, bp->posix_path);
|
|
+
|
|
+ if (res == 0)
|
|
+ {
|
|
+ /* need to select between user and system mount to same POSIX path */
|
|
+ if (!(bp->flags & MOUNT_SYSTEM)) /* user mount */
|
|
+ return 1;
|
|
+ else
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+/* sort_by_shortest_native_name: qsort callback to sort the mount entries.
|
|
+ Sort user mounts ahead of system mounts to the same POSIX path. */
|
|
+/* FIXME: should the user should be able to choose whether to
|
|
+ prefer user or system mounts??? */
|
|
+static int
|
|
+sort_by_shortest_native_name (const void *a, const void *b)
|
|
+{
|
|
+ mount_item *ap = mounts_for_sort + (*((int*) a));
|
|
+ mount_item *bp = mounts_for_sort + (*((int*) b));
|
|
+
|
|
+ /* Base weighting on the conversion that would give the shortest
|
|
+ native path. */
|
|
+ ssize_t alen = (ssize_t) strlen (ap->native_path);
|
|
+ ssize_t blen = (ssize_t) strlen (bp->native_path);
|
|
+
|
|
+ int res = alen - blen;
|
|
+
|
|
+ if (res)
|
|
+ return res; /* Path lengths differed */
|
|
+
|
|
+ /* The two paths were the same length, so just determine normal
|
|
+ lexical sorted order. */
|
|
+ res = strcmp (ap->native_path, bp->native_path);
|
|
+
|
|
+ if (res == 0)
|
|
+ {
|
|
+ /* need to select between user and system mount to same POSIX path */
|
|
+ if (!(bp->flags & MOUNT_SYSTEM)) /* user mount */
|
|
+ return 1;
|
|
+ else
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+static int
|
|
+sort_posix_subdirs_before_parents (const void *a, const void *b)
|
|
+{
|
|
+ mount_item *ap = mounts_for_sort + (*((int*) a));
|
|
+ mount_item *bp = mounts_for_sort + (*((int*) b));
|
|
+
|
|
+ if (ap->posix_pathlen > bp->posix_pathlen)
|
|
+ {
|
|
+ if (!memcmp (bp->posix_path, ap->posix_path, bp->posix_pathlen))
|
|
+ {
|
|
+ // bp is a subdir of ap (bp must be moved in-front)
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ else if (ap->posix_pathlen < bp->posix_pathlen)
|
|
+ {
|
|
+ if (!memcmp (ap->posix_path, bp->posix_path, ap->posix_pathlen))
|
|
+ {
|
|
+ // ap is a subdir of bp (good as we are)
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#define DISABLE_NEW_STUFF 0
|
|
+#define ONLY_USE_NEW_STUFF 1
|
|
+
|
|
void
|
|
mount_info::sort ()
|
|
{
|
|
for (int i = 0; i < nmounts; i++)
|
|
- native_sorted[i] = posix_sorted[i] = i;
|
|
+ native_sorted[i] = posix_sorted[i] = shortest_native_sorted[i] = longest_posix_sorted[i] = i;
|
|
/* Sort them into reverse length order, otherwise we won't
|
|
be able to look for /foo in /. */
|
|
mounts_for_sort = mount; /* ouch. */
|
|
qsort (posix_sorted, nmounts, sizeof (posix_sorted[0]), sort_by_posix_name);
|
|
qsort (native_sorted, nmounts, sizeof (native_sorted[0]), sort_by_native_name);
|
|
+ qsort (longest_posix_sorted, nmounts, sizeof (longest_posix_sorted[0]), sort_by_longest_posix_name);
|
|
+ qsort (shortest_native_sorted, nmounts, sizeof (shortest_native_sorted[0]), sort_by_shortest_native_name);
|
|
+ qsort (shortest_native_sorted, nmounts, sizeof (shortest_native_sorted[0]), sort_posix_subdirs_before_parents);
|
|
+ /* Disabling my new crap. */
|
|
+ #if DISABLE_NEW_STUFF
|
|
+ for (int i = 0; i < nmounts; i++)
|
|
+ {
|
|
+ longest_posix_sorted[i] = native_sorted[i];
|
|
+ shortest_native_sorted[i] = posix_sorted[i];
|
|
+ }
|
|
+ #else
|
|
+ #if ONLY_USE_NEW_STUFF
|
|
+ for (int i = 0; i < nmounts; i++)
|
|
+ {
|
|
+ native_sorted[i] = longest_posix_sorted[i];
|
|
+ posix_sorted[i] = shortest_native_sorted[i];
|
|
+ }
|
|
+ #endif
|
|
+ #endif
|
|
+ for (int i = 0; i < nmounts; i++)
|
|
+ {
|
|
+ mount_item *mi = mount + shortest_native_sorted[i];
|
|
+ debug_printf ("shortest_native_sorted (subdirs before parents)[%d] %12s %12s", i, mi->native_path, mi->posix_path);
|
|
+ }
|
|
+ for (int i = 0; i < nmounts; i++)
|
|
+ {
|
|
+ mount_item *mi = mount + longest_posix_sorted[i];
|
|
+ debug_printf ("longest_posix_sorted[%d] %12s %12s", i, mi->native_path, mi->posix_path);
|
|
+ }
|
|
}
|
|
|
|
/* Add an entry to the mount table.
|
|
@@ -1473,12 +1611,9 @@ mount_info::add_item (const char *native, const char *posix,
|
|
if (i == nmounts)
|
|
nmounts++;
|
|
|
|
- if (strcmp (posixtmp, "/usr/bin") == 0)
|
|
+ if (strcmp (posixtmp, "/bin") == 0)
|
|
got_usr_bin = true;
|
|
|
|
- if (strcmp (posixtmp, "/usr/lib") == 0)
|
|
- got_usr_lib = true;
|
|
-
|
|
if (posixtmp[0] == '/' && posixtmp[1] == '\0' && !(mountflags & MOUNT_CYGDRIVE))
|
|
root_idx = i;
|
|
|
|
diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h
|
|
index 0b392ca85..e6ca7fd82 100644
|
|
--- a/winsup/cygwin/mount.h
|
|
+++ b/winsup/cygwin/mount.h
|
|
@@ -169,7 +169,6 @@ class mount_info
|
|
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
|
|
@@ -181,6 +180,8 @@ class mount_info
|
|
private:
|
|
int posix_sorted[MAX_MOUNTS];
|
|
int native_sorted[MAX_MOUNTS];
|
|
+ int longest_posix_sorted[MAX_MOUNTS];
|
|
+ int shortest_native_sorted[MAX_MOUNTS];
|
|
|
|
public:
|
|
void init (bool);
|
|
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
|
|
index 1a2a6aa40..ff395d133 100644
|
|
--- a/winsup/cygwin/uinfo.cc
|
|
+++ b/winsup/cygwin/uinfo.cc
|
|
@@ -2656,7 +2656,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|
dom, name,
|
|
sid.string ((char *) sidstr),
|
|
home ?: "/home/", home ? L"" : name,
|
|
- shell ?: "/bin/bash");
|
|
+ shell ?: "/usr/bin/bash");
|
|
if (gecos)
|
|
free (gecos);
|
|
if (home)
|
|
--
|
|
2.11.1
|
|
|