[kaffe] java.io.File#isDirectory() and symbolic links

Adam Heath doogie at brainfood.com
Sat Dec 25 21:35:54 PST 2004


On Sun, 26 Dec 2004, Ito Kazumitsu wrote:

> Hi,
>
> I am afraid java.io.File#isDirectory()'s behavior of handling
> symbolic links is not the same as before.  I do not know
> which is correct, but the problem is I have an application
> system which depends on the old behavior.
>
> Test Program:
>
> import java.io.*;
>
> public class TestDirectory {
>     public static void main(String[] args) throws Exception {
>         String _filename = args[0];
>         File file=new File(_filename);
>         File dir= new File(file.getParent());
>         System.out.println("file=" + file + " dir=" + dir);
>         if (!dir.isDirectory())
>             throw new IOException("not a directory: "+dir);
>     }
> }
>
> bash$ ls -lR /tmp/test0 /tmp/test1
> /tmp/test0:
> total 4
> drwxr-xr-x  2 kaz kaz 4096 Dec 26 10:19 a
>
> /tmp/test0/a:
> total 0
>
> /tmp/test1:
> total 0
> lrwxr-xr-x  1 kaz kaz 12 Dec 26 10:20 a -> /tmp/test0/a
>
>
> Before:
>
> bash$ /usr/local/kaffe/bin/kaffe -fullversion
> ...
>   ChangeLog head   : 2004-10-08  Dalibor Topic  <robilad at kaffe.org>
> bash$ /usr/local/kaffe/bin/kaffe TestDirectory /tmp/test1/a/z
> file=/tmp/test1/a/z dir=/tmp/test1/a
> bash$
>
> Now:
>
> bash$ ~/work/kaffe-inst/bin/kaffe -fullversion
> ...
>   ChangeLog head   : 2004-12-22  Guilhem Lavaux  <guilhem at kaffe.org>
> bash$ ~/work/kaffe-inst/bin/kaffe TestDirectory /tmp/test1/a/z
> file=/tmp/test1/a/z dir=/tmp/test1/a
> java.io.IOException: not a directory: /tmp/test1/a
>    at TestDirectory.main (TestDirectory.java:10)

Hmm.  Right.  Let's see.

This behaviour changed, due to a bug when deleting a symlink that points to a
directory.  Kaffe did a normal stat(2) call on a symlink, saw it pointed to a
dir, did a rmdir on it, which failed, because the item wasn't a directory, but
a symlink.

Changing to lstat fixed that problem.

However, that causes the isDirectory code to return false for symlinks that
point to directories.  In java_io_VMFile_delete, that test is used to call
either the KRMDIR or KREMOVE syscalls.

However, upon reading remove(3), I see that it calls unlink(2) or rmdir(2) as
appropriate, depending on the type.

So, the fix is to change the lstat call in KSTAT back to stat, and call
KREMOVE unconditionally.

That will solve your isDirectory() problem, and let new
File("symlink").delete() work as well(which was a bug in bootstrap ant in
gump).




More information about the kaffe mailing list