summaryrefslogtreecommitdiffstats
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-08-25 21:18:26 +0000
committerCorinna Vinschen <corinna@vinschen.de>2005-08-25 21:18:26 +0000
commit3716969169a02e4406e73872328f7c7bd2bf9843 (patch)
treebf5b36c88705e5a88195fd6bd3e8e85f1c38c315 /winsup
parent9d13e04523cdf8d615861845a22a35add858bd0b (diff)
downloadcygnal-3716969169a02e4406e73872328f7c7bd2bf9843.tar.gz
cygnal-3716969169a02e4406e73872328f7c7bd2bf9843.tar.bz2
cygnal-3716969169a02e4406e73872328f7c7bd2bf9843.zip
* path.cc (realpath): Drop call to mount_info::conv_to_posix_path
in favor of calling path_conv with PC_POSIX flag. Align error handling closer to POSIX. As on Linux, return user space allocated memory if second parameter is NULL.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/path.cc41
2 files changed, 37 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fce488b17..cc988a008 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,12 @@
2005-08-25 Corinna Vinschen <corinna@vinschen.de>
+ * path.cc (realpath): Drop call to mount_info::conv_to_posix_path
+ in favor of calling path_conv with PC_POSIX flag. Align error
+ handling closer to POSIX. As on Linux, return user space allocated
+ memory if second parameter is NULL.
+
+2005-08-25 Corinna Vinschen <corinna@vinschen.de>
+
* path.cc (normalize_win32_path): Honor network paths. Fold more
than two leading dir separators into one. Check for dir separator
instead of just slashes to handle incoming Win32 paths correctly.
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 568072f4c..d4640898d 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3653,24 +3653,43 @@ extern "C" char *
realpath (const char *path, char *resolved)
{
extern suffix_info stat_suffixes[];
- int err;
- path_conv real_path (path, PC_SYM_FOLLOW, stat_suffixes);
+ /* Make sure the right errno is returned if path is NULL. */
+ if (!path)
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
- if (real_path.error)
- err = real_path.error;
- else
+ path_conv real_path (path, PC_SYM_FOLLOW | PC_POSIX, stat_suffixes);
+
+ /* Guard writing to a potentially invalid resolved. */
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return NULL;
+
+ /* Linux has this funny non-standard extension. If "resolved" is NULL,
+ realpath mallocs the space by itself and returns it to the application.
+ The application is responsible for calling free() then. This extension
+ is backed by POSIX, which allows implementation-defined behaviour if
+ "resolved" is NULL. That's good enough for us to do the same here. */
+
+ if (!real_path.error && real_path.exists ())
{
- err = mount_table->conv_to_posix_path (real_path.get_win32 (), resolved, 0);
- if (err == 0)
- return resolved;
+ if (!resolved)
+ {
+ resolved = (char *) malloc (strlen (real_path.normalized_path) + 1);
+ if (!resolved)
+ return NULL;
+ }
+ return strcpy (resolved, real_path.normalized_path);
}
/* FIXME: on error, we are supposed to put the name of the path
component which could not be resolved into RESOLVED. */
- resolved[0] = '\0';
-
- set_errno (err);
+ if (resolved)
+ resolved[0] = '\0';
+ set_errno (real_path.error ?: ENOENT);
return NULL;
}