diff options
author | Tom Tromey <tromey@redhat.com> | 2003-09-11 16:44:39 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2003-09-11 16:44:39 +0000 |
commit | c203255aba10d807f68097646f4aeb3feaf2cb48 (patch) | |
tree | 2bd1b3aa7b8c77927fd3714436e9b3f883b1fc83 | |
parent | 92af500d3e3f3ae08792a6e4446356321ec3ae65 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | libjava/java/io/natFilePosix.cc | 64 |
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. |