From: corinna DOT vinschen AT cityweb DOT de (Corinna Vinschen) Subject: diff to winsup981012, was Re: BUG: mount point/mount errors in B19 and B20 alphas 18 Oct 1998 17:01:44 -0700 Message-ID: <362A7BF8.D3D105E9.cygnus.cygwin32.developers@cityweb.de> References: <19981018041035 DOT 6085 DOT qmail AT hotmail DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: Christopher Faylor , cygwin32-developers AT cygnus DOT com 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)",