On Sep 23 06:58, Eric Blake wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > According to Eric Blake on 9/22/2009 3:02 PM: > > I've got a patch in testing for both of these issues. > > Does this look okay to apply? The fix in path.cc affects more than just > link, hence I had to add a new option to keep mkdir("d/",mode) still > working, while link("file","d/") now fails with the same ENOENT as Linux. > rename was tricky, as rename("file","d/") must fail whether or not d > exists, while rename("dir","d/") must succeed if d does not exist or > exists and is empty. I think I got it all, but it can't hurt to > double-check things. > > 2009-09-23 Eric Blake <e...@byu.net> > > * path.h (PC_MKDIR): New enum value. > * path.cc (check): Ensure 'a/' resolves to a directory. > * syscalls.cc (link): Fix comment. > (rename): Use correct errno for trailing '.'. Allow trailing > slash to newpath iff oldpath is directory. > * dir.cc (mkdir): Allow trailing slash. > [...] > @@ -698,7 +698,7 @@ path_conv::check (const char *src, unsig > into account during processing */ > if (tail > path_copy + 2 && isslash (tail[-1])) > { > - need_directory = 1; > + need_directory = !(opt & PC_MKDIR); > *--tail = '\0'; > } > path_end = tail; > @@ -899,7 +899,7 @@ is_virtual_symlink: > these operations again on the newly derived path. */ > else if (symlen > 0) > { > - saw_symlinks = 1; > + saw_symlinks = true; > if (component == 0 && !need_directory && !(opt & PC_SYM_FOLLOW)) > { > set_symlink (symlen); // last component of path is a symlink. > @@ -914,7 +914,7 @@ is_virtual_symlink: > else > break; > } > - else if (sym.error && sym.error != ENOENT) > + else if (sym.error && (sym.error != ENOENT || need_directory)) > { > error = sym.error; > goto out;
Urgh. I stumbled over the need_directory flag only two days ago. while debugging the symlink errno problem you reported on the list. CGF is my witness. It's the reason I made the trailing slash change in symlink rather than in path_conv::check. It's quite tricky to keep all possible cases working. Have you tested this change with the entire coreutils testsuite? It seems to be quite thorough. > @@ -1124,12 +1124,7 @@ isatty (int fd) > } > EXPORT_ALIAS (isatty, _isatty) > > -/* Under NT, try to make a hard link using backup API. If that > - fails or we are Win 95, just copy the file. > - FIXME: We should actually be checking partition type, not OS. > - Under NTFS, we should support hard links. On FAT partitions, > - we should just copy the file. > -*/ > +/* Under NT, try to make a hard link using backup API. */ Thanks for fixing the comment, but actually we're not using the backup API for some time, and we're now always under NT. I guess we should get rid of this comment entirely since the actual work is done in fhandler_disk_file::link anyway. > extern "C" int > link (const char *oldpath, const char *newpath) > @@ -1650,13 +1645,13 @@ rename (const char *oldpath, const char > if (has_dot_last_component (oldpath, true)) > { > oldpc.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes); > - set_errno (oldpc.isdir () ? EBUSY : ENOTDIR); > + set_errno (oldpc.isdir () ? EINVAL : ENOTDIR); > goto out; > } > if (has_dot_last_component (newpath, true)) > { > newpc.check (newpath, PC_SYM_NOFOLLOW, stat_suffixes); > - set_errno (!newpc.exists () ? ENOENT : newpc.isdir () ? EBUSY : > ENOTDIR); > + set_errno (!newpc.exists () ? ENOENT : newpc.isdir () ? EINVAL : > ENOTDIR); > goto out; > } > > @@ -1701,6 +1696,11 @@ rename (const char *oldpath, const char > nlen = strlen (newpath); > if (isdirsep (newpath[nlen - 1])) > { > + if (!oldpc.isdir()) > + { > + set_errno (ENOTDIR); > + goto out; > + } > stpcpy (newbuf = tp.c_get (), newpath); > while (nlen > 0 && isdirsep (newbuf[nlen - 1])) > newbuf[--nlen] = '\0'; > @@ -1718,7 +1718,7 @@ rename (const char *oldpath, const char > set_errno (EROFS); > goto out; > } > - if (new_dir_requested && !newpc.isdir ()) > + if (new_dir_requested && newpc.exists() && !newpc.isdir ()) > { > set_errno (ENOTDIR); > goto out; This part of the patch looks good to me. I'm just sweating some blood over the need_directory change in path_conv::check due to my own experience. Does it really not break something in the path handling? Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat