This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
[Patch] override-able installation_root
- From: Shaddy Baddah <helium at shaddybaddah dot name>
- To: cygwin-patches at cygwin dot com
- Date: Thu, 26 Nov 2009 01:03:12 +1100
- Subject: [Patch] override-able installation_root
Hi,
Please find attached a patch to allow for override-able
installation_root. I actually wrote this patch for release 1.7.0-52
motivated by the thread I started " [1.7] Alternative root directory.
Sort of a regression."
[http://cygwin.com/ml/cygwin/2009-07/msg00904.html]. I have forward
ported it.
The idea behind this patch is as follows. Presently, the
installation_root is fixed to be based off of the path to the cygwin
dll. This also means that the /etc/fstab must be located exactly at
..\etc\fstab relative path to the path of the folder containing the
cygwin dll.
I wished/qwish to shared a single Cygwin installation on my host, with
my guest Windows in VirtualBox. However, I need and wanted a) a
different path to home directories (because I wanted to ensure read-only
sharing) b) generally alternative configuration from /etc. This is why I
needed both an alternative /etc/fstab and /etc directory in general.
These both imply an alternative installation_root, as this is how these
"bootstrap" locations are determined.
The patch works by checking for a supplementary, manually added registry
entry, which indicates that the rootdir set by the Cygwin setup
application should be considered the installation_root. The idea is that
on the Cygwin installation "client", the administrator would manually
setup both .../Cygwin/Setup/rootdir and
.../Cygwin/Setup/rootdir_is_installation_dir.
Note, in forward porting, I had to discard a change I made to reg_key
(registry.{h,cc}) in deference to a change Corinna made that partly
mirrored my own. I am talking about the addition of the following method
(and its associates):
int get_string (const PWCHAR, PWCHAR, size_t, const PWCHAR);
However, I have found this to be slightly problematic. It resulted in me
having to explicitly cast as in:
&& (setup_reg.get_string ((const PWCHAR)L"rootdir",
setup_installation_root, PATH_MAX,
(const PWCHAR)L"") == ERROR_SUCCESS))
When faced with the same situation, to avoid the cast, I had to alter
the method to look like this:
int get_string (PCWCH, PWCHAR buf, size_t len, PCWCH def);
To be honest, I don't totally understand why it was necessary, even
though I am aware of the difference between const positioning. Perhaps
this needs a second look at? By the way, this problem pricked my
curiosity leading me to ask about "regtool/registry interfacing and
charset support" [http://cygwin.com/ml/cygwin/2009-07/msg00930.html].
winsup/cygwin/ChangeLog
2009-11-25 Shaddy Baddah <helium@shaddybaddah.name>
* include/cygwin/version.h: Added CYGWIN_INFO_SETUP_NAME registry
name for consistency
* shared.cc (init_installation_root): Switches in the setup
rootdir as the installation_root when a boolean registry entry
"rootdir_is_installation_root" is set true.
Thanks in advance for (fingers crossed, thoughtfully) considering this
patch,
Shaddy
diff -r b073827c578e -r 7754c52b6400 winsup/cygwin/include/cygwin/version.h
--- a/winsup/cygwin/include/cygwin/version.h Mon Nov 23 14:53:41 2009 +1100
+++ b/winsup/cygwin/include/cygwin/version.h Thu Nov 26 00:59:34 2009 +1100
@@ -413,6 +413,7 @@
#define CYGWIN_INFO_CYGWIN_REGISTRY_NAME "Cygwin"
#define CYGWIN_INFO_PROGRAM_OPTIONS_NAME "Program Options"
#define CYGWIN_INFO_INSTALLATIONS_NAME "Installations"
+#define CYGWIN_INFO_SETUP_NAME "setup"
/* The default cygdrive prefix. */
diff -r b073827c578e -r 7754c52b6400 winsup/cygwin/shared.cc
--- a/winsup/cygwin/shared.cc Mon Nov 23 14:53:41 2009 +1100
+++ b/winsup/cygwin/shared.cc Thu Nov 26 00:59:34 2009 +1100
@@ -91,16 +91,59 @@
RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root),
&installation_key, FALSE);
- PWCHAR w = wcsrchr (installation_root, L'\\');
- if (w)
+ reg_key setup_reg (true, KEY_READ, CYGWIN_INFO_SETUP_NAME, NULL);
+ WCHAR setup_installation_root[PATH_MAX];
+ if (setup_reg.get_int ("rootdir_is_installation_root", 0)
+ && (setup_reg.get_string ((const PWCHAR)L"rootdir",
+ setup_installation_root, PATH_MAX,
+ (const PWCHAR)L"") == ERROR_SUCCESS))
{
+ DWORD attr = GetFileAttributesW(setup_installation_root);
+ if ((attr == INVALID_FILE_ATTRIBUTES)
+ || (! (attr & FILE_ATTRIBUTE_DIRECTORY)))
+ {
+ api_fatal ("Can't initialize Cygwin installation root dir.\n"
+ "GetFileAttributesW(%p), %d",
+ setup_installation_root, attr);
+ }
+ /* lop of any trailing slash, to be consistent with the dll handling */
+ size_t last_wchr_idx = wcslen(setup_installation_root) - 1;
+ system_printf("last_wchr_idx %d\n", last_wchr_idx);
+ if ((last_wchr_idx >= 0)
+ && (setup_installation_root[last_wchr_idx] == L'\\'))
+ setup_installation_root[last_wchr_idx] = L'\0';
+
+ wcscpy(installation_root, setup_installation_root);
+ p = installation_root;
+ if (wcsncmp (p, L"\\\\?\\", 4)) /* No long path prefix. */
+ {
+ if (!wcsncasecmp (p, L"\\\\", 2)) /* UNC */
+ {
+ p = wcpcpy (p, L"\\??\\UN");
+ wcsncat (p, setup_installation_root, PATH_MAX - 6);
+ *p = L'C';
+ }
+ else
+ {
+ p = wcpcpy (p, L"\\??\\");
+ wcsncat (p, setup_installation_root, PATH_MAX - 4);
+ }
+ }
+ installation_root[1] = L'?';
+ }
+ else
+ {
+ PWCHAR w = wcsrchr (installation_root, L'\\');
+ if (w)
+ {
+ *w = L'\0';
+ w = wcsrchr (installation_root, L'\\');
+ }
+ if (!w)
+ api_fatal ("Can't initialize Cygwin installation root dir.\n"
+ "Invalid DLL path");
*w = L'\0';
- w = wcsrchr (installation_root, L'\\');
}
- if (!w)
- api_fatal ("Can't initialize Cygwin installation root dir.\n"
- "Invalid DLL path");
- *w = L'\0';
for (int i = 1; i >= 0; --i)
{