[Patch]: Last path.cc

Pierre A. Humblet pierre@phumblet.no-ip.org
Sun Apr 11 03:40:00 GMT 2004


This should take care of the issues I listed yesterday evening.

I simply don't understand the logic in normalize_win32_path
well enough to touch it intelligently. 
So I removed the final . in the dumbest way possible

For example on line 946
  else if (strchr (src, ':') == NULL && *src != '/')
(why only '/' and not '\\')?
There is a "dst_start" and a "dst_root_start" that appear
to be the same. Perhaps one of them should prevent .. from 
going back to the drive or the unc prefix.

The code in normalize_posix_path looks much cleaner. It could 
perhaps be used here as well (reiterating a FIXME to that effect).

The other changes are minor.

Pierre

2004-04-11  Pierre Humblet <pierre.humblet@ieee.org>

	* path.cc (normalize_win32_path): Detect components with only dots.
	Remove a final . if it follows '\\'.
	(slash_unc_prefix_p): Remove redundant tests.
	(mount_info::conv_to_win32_path): Only backslashify the path
	when no mount is found.
	(chdir): Do not look for components with only dots.
-------------- next part --------------
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.297
diff -u -p -r1.297 path.cc
--- path.cc	10 Apr 2004 19:24:55 -0000	1.297
+++ path.cc	10 Apr 2004 23:06:02 -0000
@@ -776,7 +776,7 @@ path_conv::check (const char *src, unsig
 	}

      /* Copy the symlink contents to the end of tmp_buf.
-	Convert slashes.  FIXME? I think it's fine / Pierre */
+	Convert slashes. */
       for (char *p = sym.contents; *p; p++)
 	*headptr++ = *p == '\\' ? '/' : *p;
       *headptr = '\0';
@@ -981,18 +981,26 @@ normalize_win32_path (const char *src, c
       /* Backup if "..".  */
       else if (src[0] == '.' && src[1] == '.'
 	       /* dst must be greater than dst_start */
-	       && dst[-1] == '\\'
-	       && (isdirsep (src[2]) || src[2] == 0))
-	{
-	  /* Back up over /, but not if it's the first one.  */
-	  if (dst > dst_root_start + 1)
-	    dst--;
-	  /* Now back up to the next /.  */
-	  while (dst > dst_root_start + 1 && dst[-1] != '\\' && dst[-2] != ':')
-	    dst--;
-	  src += 2;
-	  if (isdirsep (*src))
-	    src++;
+	       && dst[-1] == '\\')
+        {
+	  if (isdirsep (src[2]) || src[2] == 0)
+	    {
+	      /* Back up over /, but not if it's the first one.  */
+	      if (dst > dst_root_start + 1)
+		dst--;
+	      /* Now back up to the next /.  */
+	      while (dst > dst_root_start + 1 && dst[-1] != '\\' && dst[-2] != ':')
+		dst--;
+	      src += 2;
+	      if (isdirsep (*src))
+		src++;
+	    }
+	  else
+	    {
+	      int n = strspn (src, ".");
+	      if (!src[n] || isdirsep (src[n])) /* just dots... */
+		return ENOENT;
+	    }
 	}
       /* Otherwise, add char to result.  */
       else
@@ -1006,6 +1014,8 @@ normalize_win32_path (const char *src, c
       if ((dst - dst_start) >= CYG_MAX_PATH)
 	return ENAMETOOLONG;
     }
+  if (dst > dst_start + 1 && dst[-1] == '.' && dst[-2] == '\\')
+    dst--;
   *dst = 0;
   if (tail)
     *tail = dst;
@@ -1082,13 +1092,11 @@ int __stdcall
 slash_unc_prefix_p (const char *path)
 {
   char *p = NULL;
-  int ret = (isdirsep (path[0])
-	     && isdirsep (path[1])
-	     && (isalnum (path[2]) || path[2] == '.')
-	     && ((p = strpbrk (path + 3, "\\/")) != NULL));
-  if (!ret || p == NULL)
-    return ret;
-  return ret && isalnum (p[1]);
+  return (isdirsep (path[0])
+	  && isdirsep (path[1])
+	  && (isalnum (path[2]) || path[2] == '.')
+	  && ((p = strpbrk (path + 3, "\\/")) != NULL)
+	  && isalnum (p[1]));
 }

 /* conv_path_list: Convert a list of path names to/from Win32/POSIX. */
@@ -1492,11 +1500,7 @@ mount_info::conv_to_win32_path (const ch
       chroot_ok = true;
     }
   else
-    {
-      if (strchr (src_path, ':') == NULL && !slash_unc_prefix_p (src_path))
-	set_flags (flags, PATH_BINARY);
-      backslashify (src_path, dst, 0);
-    }
+    backslashify (src_path, dst, 0);

  out:
   MALLOC_CHECK;
@@ -3292,24 +3296,6 @@ chdir (const char *in_dir)
     {
       set_errno (path.error);
       syscall_printf ("-1 = chdir (%s)", dir);
-      return -1;
-    }
-
-
-  /* Look for trailing path component consisting entirely of dots.  This
-     is needed only in case of chdir since Windows simply ignores count
-     of dots > 2 here instead of returning an error code.  Counts of dots
-     <= 2 are already eliminated by normalize_posix_path. */
-  const char *p = strrchr (dir, '/');
-  if (!p)
-    p = dir;
-  else
-    p++;
-
-  size_t len = strlen (p);
-  if (len > 2 && strspn (p, ".") == len)
-    {
-      set_errno (ENOENT);
       return -1;
     }



More information about the Cygwin-patches mailing list