MSYS mode (continue)

LRN lrn1986@gmail.com
Fri Jul 26 04:03:00 GMT 2013


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 26.07.2013 05:55, Christopher Faylor wrote:
> On Thu, Jul 25, 2013 at 05:30:57PM -0400, Larry Hall (Cygwin Developers) wrote:
>> On 7/25/2013 5:07 PM, LRN wrote:
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> On 26.07.2013 00:53, Christopher Faylor wrote:
>>>> On Thu, Jul 25, 2013 at 02:20:50PM -0400, Charles Wilson wrote:
>>>>>> But underlying there's still a normal Cygwin DLL and
>>>>>> most tools could just be copied verbatim since they don't need this
>>>>>> extra functionality.
>>>>>
>>>>> And that's the bit where I disagree.  Sure, some scripting tools might
>>>>> not need adjustment, so long as their interpreter was $MSYS-enabled
>>>>> (e.g. automake -> msys-perl, msys-bash) -- because the script will "see"
>>>>> dos-style paths, so its interpreter better be able to handle them.
>>>>>
>>>>> But unless you restrict yourself to only passing around relative paths
>>>>> (or god forbid, that old "unity mount" idea), any .exe will need to live
>>>>> in one world or the other. Otherwise, how would paths be interpreted?
>>>>> Using which tools' mount table?
>>>>>
>>>>> Naturally from the command line I can compensate:
>>>>>
>>>>> msys$  /c/cygwin/bin/foobar.exe $(/c/cygwin/bin/cygpath.exe -u $(cygpath
>>>>> -d /msys/mount/table/path) )
>>>>>
>>>>> but yee gods that'd be annoying in any automated setting.
>>>>
>>>> I don't know if this helps but the vague plan is to now have two DLLs
>>>> where before you only had one.  You'd still be providing "MSYS" binaries
>>>> which relied on "MSYS.dll" but, under the hood, MSYS.dll would be only a
>>>> small dll which relied on cygwin1.dll for all of the heavy lifting.
>>>>
>>>> You'd still have a normal MSYS distribution and it would still, in theory,
>>>> support everything (with the possible exception of very lax security) that
>>>> the old MSYS did.  An MSYS release would consist of MSYS*.dll, cygwin1.dll,
>>>> bash, etc.
>>>
>>> Out of curiosity: why do you insist on having MSYS functionality in a
>>> separate dll, when it could be just part of cygwin1.dll (disableable and
>>> enableable in the same way other Cygwin features are disabled/enabled -
>>> via CYGWIN envvar)? What advantage would that give, that justifies the
>>> increase in implementation complexity (hooking up the dll, etc)? Was
>>> that justified earlier in this thread and i just neglected to read that
>>> far back?
>>
>> Yes, it was mentioned.  The idea is to keep the MSYS-specific stuff separate
>> so Cygwin functionality isn't impacted by what MSYS wants.  This reduces
>> the complexity of the Cygwin code at least.
> 
> Right.  Thanks Larry.
> 
> The bottom line is that we don't want there to be a bunch of "if
> (is_msys)"'s in the code.  We don't want to have to worry about how msys
> does things.  I don't want to have to inspect msys patches, except for
> requests for a new hook.
> 
> A hook will be a fast no-op in the pure cygwin cases.  There would be
> very little "implementation complexity".

OK.

I've attached the patch that alexey gave me recently, if pointless
cygwin->msys renames are removed from msys2, this is what msys2 boils
down to. Please specify how the hooks will look, now that you know which
points of the code need to be hooked up.

- -- 
O< ascii ribbon - stop html email! - www.asciiribbon.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (MingW32)

iQEcBAEBAgAGBQJR8fTZAAoJEOs4Jb6SI2CwoU0H/1YQSxBz9NisJcCj6wUfo07u
yE7uqieB4sxv3dEJAigBHNVYMbEEqDehY/TVFqMoRIw9SXBSpBWFMla49w8aRHeA
7JUP3+5/cyQYJHXSLBMZBAxdYmSe61PrZVXaH/fMHVuuv31457/He/GaNrM+mos+
q6QqvB2S+lVDIBfZALPyYdS+VZ7jgDVKC2Eb5oFyrEV3EOBnkOFu/PjLUzm1ewMH
X5bn9HHiqHKHUxsss2LBbtZLO75ptLdFPBF+TY83H1TJDHDb3byFGSSGtXhB9+iB
q0j6fhXEqGT+0nCaXangHtt02zx9fvUMLb6bPJ36JTrhv3F/nxEPOjnUtq7Hzm0=
=DGCV
-----END PGP SIGNATURE-----
-------------- next part --------------
diff -Naur curr_cyg/winsup/cygwin/environ.cc curr_msys/winsup/cygwin/environ.cc
--- curr_cyg/winsup/cygwin/environ.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/environ.cc	2013-07-22 06:34:55.000000000 +0400
@@ -999,7 +1021,7 @@
    prior to placing them in the string.  */
 char ** __reg3
 build_env (const char * const *envp, PWCHAR &envblock, int &envc,
-	   bool no_envblock)
+	   bool no_envblock, bool keep_posix)
 {
   int len, n;
   const char * const *srcp;
@@ -1024,6 +1046,9 @@
   for (srcp = envp, dstp = newenv, pass_dstp = pass_env; *srcp; srcp++)
     {
       bool calc_tl = !no_envblock;
+      /* Don't pass timezone environment to non-msys applications */
+      if (!keep_posix && ascii_strncasematch(*srcp, "TZ=", 3))
+        goto next1;
       /* Look for entries that require special attention */
       for (unsigned i = 0; i < SPENVS_SIZE; i++)
 	if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp)))
@@ -1104,6 +1129,13 @@
 	  conv = getwinenv (*srcp, rest, &temp);
 	  if (conv)
 	    p = conv->native;	/* Use win32 path */
+      else if (!keep_posix) {
+        char *win_arg = arg_heuristic(*srcp);
+		debug_printf("WIN32_PATH is %s", win_arg);
+		p = cstrdup1(win_arg);
+        if (win_arg != *srcp)
+          free (win_arg);
+      }
 	  else
 	    p = *srcp;		/* Don't worry about it */
 
diff -Naur curr_cyg/winsup/cygwin/environ.h curr_msys/winsup/cygwin/environ.h
--- curr_cyg/winsup/cygwin/environ.h	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/environ.h	2013-07-22 06:34:55.000000000 +0400
@@ -45,6 +45,6 @@
 extern "C" char __stdcall **cur_environ ();
 #endif
 char ** __reg3 build_env (const char * const *envp, PWCHAR &envblock,
-			  int &envc, bool need_envblock);
+			  int &envc, bool need_envblock, bool keep_posix);
 
 #define ENV_CVT -1
diff -Naur curr_cyg/winsup/cygwin/external.cc curr_msys/winsup/cygwin/external.cc
--- curr_cyg/winsup/cygwin/external.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/external.cc	2013-07-22 06:34:55.000000000 +0400
@@ -137,7 +137,7 @@
 {
   int unused_envc;
   PWCHAR envblock = NULL;
-  char **envp = build_env (env ?: cur_environ (), envblock, unused_envc, false);
+  char **envp = build_env (env ?: cur_environ (), envblock, unused_envc, false, true);
   PWCHAR p = envblock;
 
   if (envp)
diff -Naur curr_cyg/winsup/cygwin/globals.cc curr_msys/winsup/cygwin/globals.cc
--- curr_cyg/winsup/cygwin/globals.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/globals.cc	2013-07-22 06:34:55.000000000 +0400
@@ -68,7 +68,7 @@
 /* Some CYGWIN environment variable variables. */
 bool allow_glob = true;
 bool ignore_case_with_glob = false;
-bool dos_file_warning = true;
+bool dos_file_warning = false;
 winsym_t allow_winsymlinks = WSYM_sysfile;
 bool reset_com = false;
 bool pipe_byte = false;
diff -Naur curr_cyg/winsup/cygwin/include/sys/cygwin.h curr_msys/winsup/cygwin/include/sys/cygwin.h
--- curr_cyg/winsup/cygwin/include/sys/cygwin.h	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/include/sys/cygwin.h	2013-07-22 06:34:55.000000000 +0400
@@ -81,6 +81,8 @@
    to one of the above values, or to ENOMEM if malloc fails. */
 extern void *cygwin_create_path (cygwin_conv_path_t what, const void *from);
 
+extern char * arg_heuristic (char const * const);
+
 extern pid_t cygwin_winpid_to_pid (int);
 extern int cygwin_posix_path_list_p (const char *);
 extern void cygwin_split_path (const char *, char *, char *);
diff -Naur curr_cyg/winsup/cygwin/mount.cc curr_msys/winsup/cygwin/mount.cc
--- curr_cyg/winsup/cygwin/mount.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/mount.cc	2013-07-22 06:34:55.000000000 +0400
@@ -458,13 +456,13 @@
   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);
 }
@@ -1125,8 +1117,17 @@
   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)
diff -Naur curr_cyg/winsup/cygwin/path.cc curr_msys/winsup/cygwin/path.cc
--- curr_cyg/winsup/cygwin/path.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/path.cc	2013-07-22 06:34:55.000000000 +0400
@@ -1487,6 +1486,86 @@
 
 /********************** Symbolic Link Support **************************/
 
+/*
+  Create a deep copy of src as dst, while avoiding descending in origpath.
+*/
+static int
+recursiveCopy (char * src, char * dst, const char * origpath)
+{
+  WIN32_FIND_DATA dHfile;
+  HANDLE dH;
+  BOOL findfiles;
+  int srcpos = strlen (src);
+  int dstpos = strlen (dst);
+  int res = -1;
+
+  debug_printf("recursiveCopy (%s, %s)", src, dst);
+
+  /* Create the destination directory */
+  if (!CreateDirectoryEx (src, dst, NULL))
+    {
+      debug_printf("CreateDirectoryEx(%s, %s, 0) failed", src, dst);
+      __seterrno ();
+      goto done;
+    }
+  /* Descend into the source directory */
+  if (srcpos + 2 >= MAX_PATH || dstpos + 1 >= MAX_PATH)
+    {
+      set_errno (ENAMETOOLONG);
+      goto done;
+    }
+  strcat (src, "\\*");
+  strcat (dst, "\\");
+  dH = FindFirstFile (src, &dHfile);
+  debug_printf("dHfile(1): %s", dHfile.cFileName);
+  findfiles = FindNextFile (dH, &dHfile);
+  debug_printf("dHfile(2): %s", dHfile.cFileName);
+  findfiles = FindNextFile (dH, &dHfile);
+  while (findfiles)
+    {
+      /* Append the directory item filename to both source and destination */
+      int filelen = strlen (dHfile.cFileName);
+      debug_printf("dHfile(3): %s", dHfile.cFileName);
+      if (srcpos + 1 + filelen >= MAX_PATH ||
+          dstpos + 1 + filelen >= MAX_PATH)
+        {
+          set_errno (ENAMETOOLONG);
+          goto done;
+        }
+      strcpy (&src[srcpos+1], dHfile.cFileName);
+      strcpy (&dst[dstpos+1], dHfile.cFileName);
+      debug_printf("%s -> %s", src, dst);
+      if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        {
+          /* Recurse into the child directory */
+          debug_printf("%s <-> %s", src, origpath);
+          if (strcmp (src, origpath)) // avoids endless recursion
+            if (recursiveCopy (src, dst, origpath))
+              goto done;
+        }
+      else
+        {
+          /* Just copy the file */
+          if (!CopyFile (src, dst, FALSE))
+            {
+              __seterrno ();
+              goto done;
+            }
+        }
+      findfiles = FindNextFile (dH, &dHfile);
+    }
+  if (GetLastError() != ERROR_NO_MORE_FILES)
+    {
+      __seterrno ();
+      goto done;
+    }
+  res = 0;
+
+done:
+
+  return res;
+}
+
 /* Create a symlink from FROMPATH to TOPATH. */
 
 extern "C" int
@@ -1891,6 +1970,73 @@
     }
   else
     {
+      path_conv src_path;
+      src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
+      if (src_path.error)
+        {
+           set_errno (src_path.error);
+           goto done;
+        }
+      if (!src_path.isdevice () && !src_path.is_fs_special ())
+        {
+           /* MSYS copy file instead make symlink */
+
+           char * real_oldpath;
+           if (isabspath (oldpath))
+             strcpy (real_oldpath = tp.c_get (), oldpath);
+           else
+              /* Find the real source path, relative
+                 to the directory of the destination */
+             {
+                /* Determine the character position of the last path component */
+                int pos = strlen (newpath);
+                while (--pos >= 0)
+                  if (isdirsep (newpath[pos]))
+                    break;
+                /* Append the source path to the directory
+                   component of the destination */
+                if (pos+1+strlen(oldpath) >= MAX_PATH)
+                  {
+                     set_errno(ENAMETOOLONG);
+                     goto done;
+                  }
+                strcpy (real_oldpath = tp.c_get (), newpath);
+                strcpy (&real_oldpath[pos+1], oldpath);
+             }
+
+           /* As a MSYS limitation, the source path must exist. */
+		   path_conv win32_oldpath;
+           win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
+           if (!win32_oldpath.exists ())
+             {
+                set_errno (ENOENT);
+                goto done;
+             }
+
+           char *w_newpath;
+           char *w_oldpath;
+           stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
+           stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
+           if (win32_oldpath.isdir())
+             {
+                char *origpath;
+                strcpy (origpath = tp.c_get (), w_oldpath);
+                res = recursiveCopy (w_oldpath, w_newpath, origpath);
+             }
+           else
+             {
+                if (!CopyFile (w_oldpath, w_newpath, FALSE))
+                  {
+                     __seterrno ();
+                  }
+                else
+                  {
+                     res = 0;
+                  }
+             }
+           goto done;
+        }
+
       /* Default technique creating a symlink. */
       buf = tp.t_get ();
       cp = stpcpy (buf, SYMLINK_COOKIE);
@@ -3182,6 +3328,488 @@
   return res;
 }
 
+static bool
+isabswinpath (const char * path)
+{
+  int plen = strlen (path);
+  bool p0alpha = isalpha (path[0]) != 0;
+  bool p1colon = (plen > 1 && path[1] == ':');
+  bool rval = 
+         (   ((plen == 2) && p0alpha && p1colon)
+          || (  (plen > 2) 
+	      && p0alpha 
+	      && p1colon 
+	      && (strchr (&path[2], ':') == (char *)NULL)
+	     )
+	  || (   plen > 3 
+	      && path[0] == '\\' 
+	      && path[1] == '\\' 
+	      && path[3] == '\\'
+	     )
+	 );
+    return rval;
+}
+
+static char *
+ScrubRetpath (char * const retpath)
+{ 
+  char * sspath = (char *)retpath;
+  //
+  // Check for null path because Win32 doesn't like them.
+  // I.E.:  Path lists of c:/foo;;c:/bar need changed to 
+  // c:/foo;c:/bar.
+  //
+  // This need be executed only if we actually converted the path.
+  //
+  while (*sspath)
+    {
+      if (*sspath == ';' && sspath[1] == ';')
+	  for (char *i = sspath; *i; i++)
+	      *i = *(i + 1);
+      else
+	sspath++;
+    }
+  if (*(sspath - 1) == ';')
+    *(sspath - 1) = '\0';
+
+  //
+  // If we modified the path then convert all / to \ if we have a path list
+  // else convert all \ to /.
+  // 
+  if ((strchr (retpath, ';')))
+  {
+    backslashify (retpath, retpath, 0);
+  } else
+  {
+    slashify (retpath, retpath, 0);
+  }
+  debug_printf("returning: %s", retpath);
+  return retpath;
+}
+
+//
+// The returned pointer should be freed with free unless,
+// as it turns out, it is equal to the input pointer.
+//
+extern "C" char *
+arg_heuristic (char const * const arg)
+{
+
+  int arglen = (arg ? strlen (arg): 0);
+  
+  if (arglen == 0)
+  {
+    char *retpath = (char *)malloc (sizeof (char));
+    memset (retpath, 0, sizeof (char));
+    return retpath;
+  }
+
+  debug_printf("Input value: (%s)", arg);
+
+  //
+  // copy of the path string that we can overwrite
+  //
+  char *spath = (char *)alloca (arglen + 1);
+  memcpy (spath, arg, arglen + 1);
+  
+  char * sspath;
+  
+  //
+  // retpath contains the converted path string to be returned
+  //
+  char *retpath = (char *)malloc(((MAX_PATH - arglen) > 0) ? 
+      MAX_PATH : arglen + MAX_PATH);
+  memset (retpath, 0, MAX_PATH);
+  int retpath_len = 0;
+  int retpath_buflen = MAX_PATH;
+    
+#define retpathcat(retstr) \
+  retpath_len += strlen(retstr); \
+  if (retpath_buflen <= retpath_len) \
+    { \
+      retpath_buflen = ((retpath_buflen * 2 <= retpath_len) ? \
+	  retpath_len + 1 : retpath_buflen * 2); \
+      retpath = (char *)realloc (retpath, retpath_buflen); \
+    } \
+  strcat (retpath, retstr);
+
+#define retpathcpy(retstr) \
+  retpath_len = strlen (retstr); \
+  *retpath = '\0'; \
+  if (retpath_buflen <= retpath_len ) \
+    { \
+      retpath_buflen = ((retpath_buflen * 2 <= retpath_len) ? \
+	  retpath_len + 1 : retpath_buflen * 2); \
+      retpath = (char *)realloc (retpath, retpath_buflen); \
+    } \
+  strcpy (retpath, retstr);
+
+  //
+  // Just return win32 paths and path lists.
+  //
+  if (isabswinpath (arg) 
+      || (strchr (arg, ';') > 0)
+      )
+    {
+      debug_printf("returning Win32 absolute path: %s", arg);
+      return ((char *)arg);
+    }
+  //
+  // Multiple forward slashes are treated special,
+  // Remove one and return for the form of //foo or ///bar
+  // but just return for the form of //server/share.
+  //
+  else if (arg[0] == '/' && arg[1] == '/')
+    {
+      int tidx = 2;
+      while (spath[tidx] && spath[tidx] == '/')
+	  tidx++;
+      if (strchr (&spath[tidx], '/'))
+	{
+	  retpathcpy (spath);
+	}
+      else
+	{
+	  retpathcpy (&spath[1]);
+	}
+      return ScrubRetpath (retpath);
+    }
+  //
+  // special case confusion elimination
+  // Translate a path that looks similar to /c: to c:/.
+  //
+  else if (arg[0] == '/' && isabswinpath (arg + 1))
+    {
+      retpathcpy (&arg[1]);
+      return ScrubRetpath (retpath);
+    }
+  //
+  // Check for variable set.
+  //
+  else if ((sspath = strchr(spath, '=')) && isalpha (spath[0]))
+    {
+      if (isabswinpath (sspath + 1)) {
+	debug_printf("returning: %s", arg);
+	return (char *)arg;
+      }
+      char *swin32_path = arg_heuristic(sspath + 1);
+      if (swin32_path == (sspath + 1)) {
+	debug_printf("returning: %s", arg);
+	return (char *)arg;
+      }
+      *sspath = '\0';
+      retpathcpy (spath);
+      retpathcat ("=");
+      retpathcat (swin32_path);
+      free (swin32_path);
+      return ScrubRetpath (retpath);
+    }
+  //
+  // Check for paths after commas, if string begins with a '-' character.
+  //
+  else if ((sspath = strchr(spath, ',')) && spath[0] == '-')
+    {
+      if (isabswinpath (sspath + 1)) {
+	debug_printf("returning: %s", arg);
+	return (char *)arg;
+      }
+      char *swin32_path = arg_heuristic(sspath + 1);
+      if (swin32_path == (sspath + 1)) {
+	debug_printf("returning: %s", arg);
+	return (char *)arg;
+      }
+      *sspath = '\0';
+      retpathcpy (spath);
+      retpathcat (",");
+      retpathcat (swin32_path);
+      free (swin32_path);
+      return ScrubRetpath (retpath);
+    }
+  //
+  // Check for POSIX path lists.
+  // But we have to allow processing of quoted strings and switches first
+  // which uses recursion so this code will be seen again.
+  //
+  else 
+    {
+      sspath = strchr (spath, ':');
+      //
+      // Prevent http://some.string/ from being modified.
+      // 
+      if ((sspath > 0 && strlen (sspath) > 2)
+	  && (sspath[1] == '/')
+	  && (sspath[2] == '/')
+	  )
+	{
+	  debug_printf("returning: %s", arg);
+	  return ((char *)arg);
+	}
+      else
+      if ((sspath > 0)
+	   && (strchr (spath, '/') > 0)
+	   // 
+	   // Prevent strings beginning with -, ", ', or @ from being processed,
+	   // remember that this is a recursive routine.
+	   // 
+	   && (strchr ("-\"\'@", spath[0]) == 0)
+	   // 
+	   // Prevent ``foo:echo /bar/baz'' from being considered a path list.
+	   // 
+	   && (strlen (sspath) > 1 && strchr (":./", sspath[1]) > 0)
+	   )
+    {
+      //
+      // Yes, convert to Win32 path list.
+      //
+      while (sspath)
+	{
+	  *sspath = '\0';
+	  char *swin32_path = arg_heuristic (spath);
+	  //
+	  // Just ignore sret; swin32_path has the value we need.
+	  //
+	  retpathcat (swin32_path);
+	  if (swin32_path != spath)
+	    free (swin32_path);
+	  spath = sspath + 1;
+	  sspath = strchr (spath, ':');
+	  retpathcat (";");
+	  //
+	  // Handle the last path in the list.
+	  //
+	  if (!sspath)
+	    {
+	      char *swin32_path = arg_heuristic (spath);
+	      retpathcat (swin32_path);
+	      if (swin32_path != spath)
+		free (swin32_path);
+	    }
+	}
+      return ScrubRetpath (retpath);
+    }
+  else
+    {
+      switch (spath[0])
+	{
+	case '/':
+	  //
+	  // Just a normal POSIX path.
+	  //
+	  {
+	    //
+	    // Convert only up to a ".." path component, and
+	    // keep all what follows as is.
+	    //
+	    sspath = strstr (spath, "/..");
+	    if (sspath)
+	      {
+		*sspath = '\0';
+		char *swin32_path = arg_heuristic (spath);
+		if (swin32_path == spath)
+		  {
+		    debug_printf("returning: %s", arg);
+		    return ((char *)arg);
+		  }
+		retpathcpy (swin32_path);
+		retpathcat ("/");
+		retpathcat (sspath+1);
+		free (swin32_path);
+		return ScrubRetpath (retpath);
+	      }
+		if (strcmp(spath, "/dev/null") == 0)
+	      {
+		retpathcpy("nul");
+		return ScrubRetpath (retpath);
+	      }
+	    path_conv p (spath, 0);
+	    if (p.error)
+	      {
+		set_errno(p.error);
+		debug_printf("returning: %s", arg);
+		return ((char *)arg);
+	      }
+	    retpathcpy (p.get_win32 ());
+	    return ScrubRetpath (retpath);
+	  }
+	case '-':
+	  //
+	  // here we check for POSIX paths as attributes to a POSIX switch.
+	  //
+	  sspath = strchr (spath, '=');
+	  if (sspath)
+	    {
+	      //
+	      // just use recursion if we find a set variable token.
+	      //
+	      *sspath = '\0';
+	      if (isabswinpath (sspath + 1)) {
+		debug_printf("returning: %s", arg);
+		return (char *)arg;
+	      }
+	      char *swin32_path = arg_heuristic(sspath + 1);
+	      if (swin32_path == sspath + 1)
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	      retpathcpy (spath);
+	      retpathcat ("=");
+	      retpathcat (swin32_path);
+	      free (swin32_path);
+	      return ScrubRetpath (retpath);
+	    }
+	  else
+	    {
+	      //
+	      // Check for single letter option with a
+	      // path argument attached, eg -I/include */
+	      //
+	      if (spath[1] && spath[2] == '/')
+		{
+		  debug_printf("spath = %s", spath);
+		  sspath = spath + 2;
+		  char *swin32_path = arg_heuristic (sspath);
+		  if (swin32_path == sspath)
+		    {
+		      debug_printf("returning: %s", arg);
+		      return ((char *)arg);
+		    }
+		  sspath = (char *)spath;
+		  sspath++;
+		  sspath++;
+		  *sspath = '\0';
+		  retpathcpy (spath);
+		  *sspath = '/';
+		  retpathcat (swin32_path);
+		  free (swin32_path);
+		  return ScrubRetpath (retpath);
+		}
+	      else
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	    }
+	  break;
+	case '@':
+	  //
+	  // here we check for POSIX paths as attributes to a response
+	  // file argument (@file). This is specifically to support
+	  // MinGW binutils and gcc.
+	  //
+	  sspath = spath + 1;
+	  if (isabswinpath (sspath))
+	    {
+	      debug_printf("returning: %s", arg);
+	      return (char *)arg;
+	    }
+	  if (spath[1] == '/')
+	    {
+	      debug_printf("spath = %s", spath);
+	      char *swin32_path = arg_heuristic (sspath);
+	      if (swin32_path == sspath)
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	      sspath = (char *)spath;
+	      sspath++;
+	      *sspath = '\0';
+	      retpathcpy (spath);
+	      *sspath = '/';
+	      retpathcat (swin32_path);
+	      free (swin32_path);
+	      return ScrubRetpath (retpath);
+	    }
+	  else
+	    {
+	      debug_printf("returning: %s", arg);
+	      return ((char *)arg);
+	    }
+	  break;
+	case '"':
+	  //
+	  // Handle a double quote case.
+	  //
+	  debug_printf ("spath: %s", spath);
+	  if (spath[1] == '/')
+	    {
+	      retpathcpy ("\"");
+	      char *tpath = strchr(&spath[1], '"');
+	      if (tpath)
+		*tpath = (char)NULL;
+	      char *swin32_path = arg_heuristic (&spath[1]);
+	      if (swin32_path == &spath[1])
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	      retpathcat (swin32_path);
+	      free (swin32_path);
+	      if (tpath)
+		retpathcat ("\"");
+	      return ScrubRetpath (retpath);
+	    }
+	  debug_printf("returning: %s", arg);
+	  return ((char *)arg);
+	case '\'':
+	  //
+	  // Handle a single quote case.
+	  //
+	  debug_printf ("spath: %s", spath);
+	  if (spath[1] == '/')
+	    {
+	      retpathcpy ("'");
+	      char *tpath = strchr(&spath[1], '\'');
+	      if (tpath)
+		*tpath = (char)NULL;
+	      char *swin32_path = arg_heuristic (&spath[1]);
+	      if (swin32_path == &spath[1])
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	      retpathcat (swin32_path);
+	      free (swin32_path);
+	      if (tpath)
+		retpathcat ("'");
+	      return ScrubRetpath (retpath);
+	    }
+	  debug_printf("returning: %s", arg);
+	  return ((char *)arg);
+	default:
+	  //
+	  // This takes care of variable_foo=/bar/baz
+	  //
+	  if ((sspath = strchr(spath, '=')) && (sspath[1] == '/'))
+	    {
+	      sspath[1] = '\0';
+	      retpathcpy (spath);
+	      sspath[1] = '/';
+	      char *swin32_path = arg_heuristic (&sspath[1]);
+	      if (swin32_path == &sspath[1])
+		{
+		  debug_printf("returning: %s", arg);
+		  return ((char *)arg);
+		}
+	      retpathcat (swin32_path);
+	      free (swin32_path);
+	      return ScrubRetpath (retpath);
+	    }
+	  //
+	  // Oh well, nothing special found, set win32_path same as path.
+	  //
+	  debug_printf("returning: %s", arg);
+	  return ((char *)arg);
+	}
+      }
+    }
+  // I should not get to this point.
+  assert (false);
+  debug_printf("returning: %s", arg);
+  return ScrubRetpath (retpath);
+}
+
 /******************** Exported Path Routines *********************/
 
 /* Cover functions to the path conversion routines.
@@ -4572,6 +5200,15 @@
   else
     tocopy = posix;
 
+  // Make sure that we have forward slashes always.
+  char *pstr;
+  pstr = strchr(tocopy, '\\');
+  while (pstr)
+    {
+      *pstr = '/';
+      pstr = strchr(pstr, '\\');
+    }
+
   debug_printf ("posix %s", posix);
   if (strlen (tocopy) >= ulen)
     {
diff -Naur curr_cyg/winsup/cygwin/spawn.cc curr_msys/winsup/cygwin/spawn.cc
--- curr_cyg/winsup/cygwin/spawn.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/spawn.cc	2013-07-22 06:34:55.000000000 +0400
@@ -407,12 +407,26 @@
 	  moreinfo->argc = newargv.argc;
 	  moreinfo->argv = newargv;
 	}
-      else if (!cmd.fromargv (newargv, real_path.get_win32 (),
+      else
+    {
+	    for (int i = 0; i < newargv.argc; i++)
+	      {
+            //convert argv to win32
+	        int newargvlen = strlen (newargv[i]);
+	        char *tmpbuf = (char *)malloc (newargvlen + 1);
+	        memcpy (tmpbuf, newargv[i], newargvlen + 1);
+	        tmpbuf = arg_heuristic(tmpbuf);
+	        debug_printf("newargv[%d] = %s", i, newargv[i]);
+	        newargv.replace (i, tmpbuf);
+	        free (tmpbuf);
+	      }
+        if (!cmd.fromargv (newargv, real_path.get_win32 (),
 				   real_path.iscygexec ()))
-	{
-	  res = -1;
-	  goto out;
-	}
+	      {
+	        res = -1;
+	        goto out;
+	      }
+    }
 
 
       if (mode != _P_OVERLAY || !real_path.iscygexec ()
@@ -537,11 +551,11 @@
 
   cygbench ("spawn-worker");
 
-  if (!real_path.iscygexec())
+  if (!real_path.iscygexec ())
     ::cygheap->fdtab.set_file_pointers_for_exec ();
 
   moreinfo->envp = build_env (envp, envblock, moreinfo->envc,
-			      real_path.iscygexec ());
+			      real_path.iscygexec (), real_path.iscygexec ());
   if (!moreinfo->envp || !envblock)
     {
       set_errno (E2BIG);
diff -Naur curr_cyg/winsup/cygwin/uname.cc curr_msys/winsup/cygwin/uname.cc
--- curr_cyg/winsup/cygwin/uname.cc	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/uname.cc	2013-07-22 06:34:55.000000000 +0400
@@ -29,7 +29,9 @@
   char *snp = strstr  (cygwin_version.dll_build_date, "SNP");
 
   memset (name, 0, sizeof (*name));
-  __small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
+  char* msystem = getenv("MSYSTEM");
+  const char *msystem_cygwin = "CYGWIN";
+  __small_sprintf (name->sysname, "%s_%s", msystem ? msystem : msystem_cygwin, wincap.osname ());
 
   /* Add a hint to the sysname, that we're running under WOW64.  This might
      give an early clue if somebody encounters problems. */
diff -Naur curr_cyg/winsup/cygwin/winf.h curr_msys/winsup/cygwin/winf.h
--- curr_cyg/winsup/cygwin/winf.h	2013-07-21 23:30:19.000000000 +0400
+++ curr_msys/winsup/cygwin/winf.h	2013-07-22 06:34:55.000000000 +0400
@@ -53,6 +53,10 @@
 	calloced = 1;
       }
   }
+  void replace (int i, const char *arg)
+  {
+    argv[i] = cstrdup1 (arg);
+  }
   void dup_all ()
   {
     for (int i = calloced; i < argc; i++)
@@ -76,6 +80,8 @@
   void prepend (const char *, int);
   void __reg2 finish (bool);
   bool __reg3 fromargv(av&, const char *, bool);;
+  operator char *() {return buf;}
+  size_t idx() {return ix;}
   operator size_t () const { return ix + 1; }
   operator const char * () const { return buf; }
   operator wchar_t * ()


More information about the Cygwin-developers mailing list