Index: dir.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dir.cc,v retrieving revision 1.123 diff -u -p -r1.123 dir.cc --- dir.cc 28 Nov 2008 09:04:35 -0000 1.123 +++ dir.cc 23 Sep 2009 12:58:26 -0000 @@ -1,6 +1,6 @@ /* dir.cc: Posix directory-related routines - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -278,7 +278,7 @@ mkdir (const char *dir, mode_t mode) if (efault.faulted (EFAULT)) return -1; - if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW))) + if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW | PC_MKDIR))) goto done; /* errno already set */; if (fh->error ()) Index: path.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/path.cc,v retrieving revision 1.565 diff -u -p -r1.565 path.cc --- path.cc 22 Sep 2009 09:24:30 -0000 1.565 +++ path.cc 23 Sep 2009 12:58:26 -0000 @@ -622,8 +622,8 @@ path_conv::check (const char *src, unsig char *tmp_buf = tp.t_get (); char *THIS_path = tp.c_get (); symlink_info sym; - bool need_directory = 0; - bool saw_symlinks = 0; + bool need_directory = false; + bool saw_symlinks = false; bool add_ext = false; bool is_relpath; char *tail, *path_end; @@ -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; Index: path.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/path.h,v retrieving revision 1.136 diff -u -p -r1.136 path.h --- path.h 26 Aug 2009 20:32:35 -0000 1.136 +++ path.h 23 Sep 2009 12:58:26 -0000 @@ -1,7 +1,7 @@ /* path.h: path data structures Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008 Red Hat, Inc. + 2006, 2007, 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -49,15 +49,16 @@ extern suffix_info stat_suffixes[]; enum pathconv_arg { - PC_SYM_FOLLOW = 0x0001, - PC_SYM_NOFOLLOW = 0x0002, - PC_SYM_CONTENTS = 0x0008, - PC_NOFULL = 0x0010, - PC_NULLEMPTY = 0x0020, - PC_CHECK_EA = 0x0040, - PC_POSIX = 0x0080, - PC_NOWARN = 0x0100, - PC_NO_ACCESS_CHECK = 0x00800000 + PC_SYM_FOLLOW = 0x0001, /* Resolve all symlinks. */ + PC_SYM_NOFOLLOW = 0x0002, /* Operate on symlink. */ + PC_SYM_CONTENTS = 0x0008, /* Perform readlink. */ + PC_NOFULL = 0x0010, /* Leave relative path short. */ + PC_NULLEMPTY = 0x0020, /* Reject "" with ENOENT. */ + PC_CHECK_EA = 0x0040, /* Unused? */ + PC_POSIX = 0x0080, /* Expect / separator. */ + PC_NOWARN = 0x0100, /* Don't warn about DOS names. */ + PC_MKDIR = 0x0200, /* About to be created via mkdir. */ + PC_NO_ACCESS_CHECK = 0x00800000 /* Skip access check on tail. */ }; #define PC_NONULLEMPTY -1 Index: syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.533 diff -u -p -r1.533 syscalls.cc --- syscalls.cc 22 Sep 2009 12:13:53 -0000 1.533 +++ syscalls.cc 23 Sep 2009 12:58:26 -0000 @@ -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. */ 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;