aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2003-09-11 16:44:39 +0000
committerTom Tromey <tromey@gcc.gnu.org>2003-09-11 16:44:39 +0000
commitc203255aba10d807f68097646f4aeb3feaf2cb48 (patch)
tree2bd1b3aa7b8c77927fd3714436e9b3f883b1fc83
parent92af500d3e3f3ae08792a6e4446356321ec3ae65 (diff)
downloadgcc-c203255aba10d807f68097646f4aeb3feaf2cb48.zip
gcc-c203255aba10d807f68097646f4aeb3feaf2cb48.tar.gz
gcc-c203255aba10d807f68097646f4aeb3feaf2cb48.tar.bz2
natFilePosix.cc (getCanonicalPath): Handle case where file does not exist.
* java/io/natFilePosix.cc (getCanonicalPath): Handle case where file does not exist. From-SVN: r71307
-rw-r--r--libjava/ChangeLog5
-rw-r--r--libjava/java/io/natFilePosix.cc64
2 files changed, 68 insertions, 1 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 1021607..8a633e6 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,8 @@
+2003-09-11 Tom Tromey <tromey@redhat.com>
+
+ * java/io/natFilePosix.cc (getCanonicalPath): Handle case where
+ file does not exist.
+
2003-09-10 Anthony Green <green@redhat.com>
* gnu/java/net/natPlainDatagramSocketImplWin32.cc (peekData):
diff --git a/libjava/java/io/natFilePosix.cc b/libjava/java/io/natFilePosix.cc
index 4946cfc..a1eb1c7 100644
--- a/libjava/java/io/natFilePosix.cc
+++ b/libjava/java/io/natFilePosix.cc
@@ -118,7 +118,69 @@ java::io::File::getCanonicalPath (void)
#ifdef HAVE_REALPATH
if (realpath (buf, buf2) == NULL)
- throw new IOException (JvNewStringLatin1 (strerror (errno)));
+ {
+ // If realpath failed, we have to come up with a canonical path
+ // anyway. We do this with purely textual manipulation.
+ // FIXME: this isn't perfect. You can construct a case where
+ // we get a different answer from the JDK:
+ // mkdir -p /tmp/a/b/c
+ // ln -s /tmp/a/b /tmp/a/z
+ // ... getCanonicalPath("/tmp/a/z/c/nosuchfile")
+ // We will give /tmp/a/z/c/nosuchfile, while the JDK will
+ // give /tmp/a/b/c/nosuchfile.
+ int out_idx;
+ if (buf[0] != '/')
+ {
+ // Not absolute, so start with current directory.
+ if (getcwd (buf2, sizeof (buf2)) == NULL)
+ throw new IOException ();
+ out_idx = strlen (buf2);
+ }
+ else
+ {
+ buf2[0] = '/';
+ out_idx = 1;
+ }
+ int in_idx = 0;
+ while (buf[in_idx] != '\0')
+ {
+ // Skip '/'s.
+ while (buf[in_idx] == '/')
+ ++in_idx;
+ int elt_start = in_idx;
+ // Find next '/' or end of path.
+ while (buf[in_idx] != '\0' && buf[in_idx] != '/')
+ ++in_idx;
+ if (in_idx == elt_start)
+ {
+ // An empty component means we've reached the end.
+ break;
+ }
+ int len = in_idx - elt_start;
+ if (len == 1 && buf[in_idx] == '.')
+ continue;
+ if (len == 2 && buf[in_idx] == '.' && buf[in_idx + 1] == '.')
+ {
+ // Found ".." component, lop off last part from existing
+ // buffer.
+ --out_idx;
+ while (out_idx > 0 && buf[out_idx] != '/')
+ --out_idx;
+ // Can't go up past "/".
+ if (out_idx == 0)
+ ++out_idx;
+ }
+ else
+ {
+ // Append a real path component to the output.
+ if (out_idx > 1)
+ buf2[out_idx++] = '/';
+ strncpy (&buf2[out_idx], &buf[elt_start], len);
+ out_idx += len;
+ }
+ }
+ buf[out_idx] = '\0';
+ }
// FIXME: what encoding to assume for file names? This affects many
// calls.