Mail Archives: cygwin-developers/1998/10/18/17:01:44
Christopher Faylor wrote:
>
> On Sun, Oct 18, 1998 at 12:48:57PM +0200, Corinna Vinschen wrote:
> >Ron Parker wrote:
> >>
> >> I have D:\unix mounted as root the directory /usr exists and D:\usr is
> >> mounted as /usr. If archive.tar contains usr/file.txt, when I "cd /"
> >> and "tar xf archive.tar" then file.txt is extracted to D:\unix\usr not
> >> D:\usr. This is the mount point not the mount.
> >>
> >> This occurs with B19 and the B20 alphas.
> >>
> >> I cannot currently investigate this, but I thought it should be
> >> reported.
> > [...]
>
> I think we can all generate failing scenarios. This particular problem
> has been in cygwin for some time. If anyone wants to submit a patch
> we'd welcome including it in b20.
The problem seems to be only in mount_info::conv_to_win32_path()
in the part, which generates relativ paths. I don't know, if I'm able
to explain it well, but I will try it in a shortened code example:
Line 1 is path.cc, line 626, latest winsup-snapshot:
1: int rc = normalize_posix_path (cwd, src_path, pathbuf);
2: [...]
3: for (int i = 0; i < nmounts; ++i)
4: {
5: if (! path_prefix_p (mount[i].path, pathbuf, mount[i].pathlen))
6: continue;
7: int got_rel_p = 0;
8: if (win32_path != NULL
9: && ! SLASH_P (*src_path)
10: && path_prefix_p (cwd, pathbuf, strlen (cwd)))
11: {
12: if (path_prefix_p (cwd, mount[i].path, strlen (cwd)))
13: {
14: if (strcmp (pathbuf, mount[i].path) == 0)
15: strcpy (win32_path, ".");
16: [...]
17: got_rel_p = 1;
18: }
Imagine this mounts:
Device Directory
d: /usr
c: /
If cwd is /, and you initiate a `cd usr', the following happens:
Line 1: cwd = "/", src_path = "usr", pathbuf = "/usr"
Line 5: mount[0].path = "/usr"
Line 10: path_prefix_p("/", "/usr", 1) --> TRUE
Line 12: path_prefix_p("/", "/usr", 1) --> TRUE
Line 14: strcmp("/usr", "/usr") --> 0
--> Line 15: strcpy(win32_path, ".")
Bingo!
In the same manner, you can really generate more failing scenarios!
Killing all the code, which creates relativ paths (this is the
`if' and it's related code beginning in line 8 in the example)
seems to remove all revealed problems. I have tested it in
two mount scenarios and with combinations of cd, ls and tar.
It works correct in my environment, now.
Regards
Corinna
------- snip --------
*** path.cc.orig Mon Oct 19 00:07:22 1998
--- path.cc Mon Oct 19 00:24:24 1998
*************** mount_info::conv_to_win32_path (const ch
*** 638,683 ****
/* SRC_PATH is in the mount table. */
- /* Compute relative path if asked to and able to. */
- int got_rel_p = 0;
- if (win32_path != NULL
- && ! SLASH_P (*src_path)
- /* Ensure the path didn't ../ out of cwd.
- There are times when we could keep ../foo as is, but
- normalize_posix_path strips all ../'s and it's [currently]
too
- much work to deal with them. */
- && path_prefix_p (cwd, pathbuf, strlen (cwd)))
- {
- if (path_prefix_p (cwd, mount[i].path, strlen (cwd)))
- {
- if (strcmp (pathbuf, mount[i].path) == 0)
- strcpy (win32_path, ".");
- else
- {
- int n = strlen (cwd);
- if (n > 1)
- n++;
- strcpy (win32_path, pathbuf + n);
- }
- }
- else
- {
- /* must be path_prefix_p (mount[i].path, cwd,
- mount[i].pathlen) */
- if (strcmp (pathbuf, cwd) == 0)
- strcpy (win32_path, ".");
- else
- strcpy (win32_path, pathbuf + strlen (cwd) + 1);
- }
- backslashify (win32_path, win32_path, trailing_slash_p);
- got_rel_p = 1;
- }
-
/* If we've matched / and the path begins with the slash drive
prefix,
or the UNC path prefix, break out. If the slash drive path was
mounted, it would have matched already. */
! if (! got_rel_p
! && strcmp (mount[i].path, "/") == 0
&& (slash_drive_prefix_p (pathbuf) ||
slash_unc_prefix_p(pathbuf)))
break;
--- 638,647 ----
/* SRC_PATH is in the mount table. */
/* If we've matched / and the path begins with the slash drive
prefix,
or the UNC path prefix, break out. If the slash drive path was
mounted, it would have matched already. */
! if (strcmp (mount[i].path, "/") == 0
&& (slash_drive_prefix_p (pathbuf) ||
slash_unc_prefix_p(pathbuf)))
break;
*************** mount_info::conv_to_win32_path (const ch
*** 686,692 ****
char *p = NULL;
if (full_win32_path != NULL)
p = full_win32_path;
! else if (win32_path != NULL && ! got_rel_p)
p = win32_path;
if (p != NULL)
{
--- 650,656 ----
char *p = NULL;
if (full_win32_path != NULL)
p = full_win32_path;
! else if (win32_path != NULL)
p = win32_path;
if (p != NULL)
{
*************** mount_info::conv_to_win32_path (const ch
*** 700,706 ****
strcpy (p + j, pathbuf + mount[i].pathlen);
backslashify (p, p, trailing_slash_p);
}
! if (win32_path != NULL && ! got_rel_p && win32_path != p)
strcpy (win32_path, p);
debug_printf ("%s = conv_to_win32_path (%s)",
--- 664,670 ----
strcpy (p + j, pathbuf + mount[i].pathlen);
backslashify (p, p, trailing_slash_p);
}
! if (win32_path != NULL && win32_path != p)
strcpy (win32_path, p);
debug_printf ("%s = conv_to_win32_path (%s)",
- Raw text -