summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/path.cc17
2 files changed, 18 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 5ea8456a8..d3d921426 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2009-09-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (symlink_worker): Rework error handling to generate Linux
+ compatible errno in case of trailing slash in newpath.
+
2009-09-22 Eric Blake <ebb9@byu.net>
* dtable.h (OPEN_MAX_MAX): New macro.
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 223cc2331..89552d999 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1376,6 +1376,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
tmp_pathbuf tp;
unsigned check_opt;
bool mk_winsym = use_winsym;
+ bool has_trailing_dirsep = false;
/* POSIX says that empty 'newpath' is invalid input while empty
'oldpath' is valid -- it's symlink resolver job to verify if
@@ -1395,12 +1396,13 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
goto done;
}
- len = strlen (newpath);
/* Trailing dirsep is a no-no. */
- if (isdirsep (newpath[len - 1]))
+ len = strlen (newpath);
+ has_trailing_dirsep = isdirsep (newpath[len - 1]);
+ if (has_trailing_dirsep)
{
- set_errno (ENOENT);
- goto done;
+ newpath = strdup (newpath);
+ ((char *) newpath)[len - 1] = '\0';
}
check_opt = PC_SYM_NOFOLLOW | PC_POSIX | (isdevice ? PC_NOWARN : 0);
@@ -1433,6 +1435,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
set_errno (EEXIST);
goto done;
}
+ if (has_trailing_dirsep && !win32_newpath.exists ())
+ {
+ set_errno (ENOENT);
+ goto done;
+ }
if (!isdevice && win32_newpath.fs_is_nfs ())
{
@@ -1667,6 +1674,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
done:
syscall_printf ("%d = symlink_worker (%s, %s, %d, %d)", res, oldpath,
newpath, mk_winsym, isdevice);
+ if (has_trailing_dirsep)
+ free ((void *) newpath);
return res;
}