This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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)
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]