Sun Java6 java.io.File#renameTo(File) でのファイル名変更は solaris では不可分な操作

Java6 の java.io.File#renameTo(File) のjavadocには以下のような記述がある。

この抽象パス名が示すファイルの名前を変更します。

このメソッドの動作の多くの部分は、本質的にプラットフォーム依存です。名前の変更操作では、ファイルをファイルシステム間で移動できないことがあります。この操作は不可分でないことがあります。また、移動先の抽象パス名を持つファイルがすでに存在する場合は、この操作が成功しない可能性があります。名前の変更操作が成功したことを確認するために、常に戻り値を調べるようにしてください。

Oracle Technology Network for Java Developers

まさか不可分でない可能性が…。VMの実装による違いって怖い。アプリからすると悩ましいところ。でもまぁUnix系OSは不可分なんだろうなと思いつつ、とりあえず Solaris (とLinux)でjava.io.File#renameTo(File)が不可分(=リネームされているかされていないかのどちらかの状態のみ)か調べるためJVMのコードを追ってみた。要は、rename(2)に行き着くか。
追っていたネイティブコード中に、

#ifdef __solaris__
...
#elif defined(__linux___)
...
#endif

のような記述があったから、SolarisLinuxも同じことが言える(のだろうきっと)。以下、コードから適当に抜粋している。

まずは java.io.File の renameTo(File)

JDKに含まれるソースコードの中にある、java/io/File.java

    public boolean renameTo(File dest) {
	SecurityManager security = System.getSecurityManager();
	if (security != null) {
	    security.checkWrite(path);
	    security.checkWrite(dest.path);
	}
	return fs.rename(this, dest);
    }

    static private FileSystem fs = FileSystem.getFileSystem();
続いて java.io.FileSystem の getFileSystem()

こちらもJDK付属ソースコードにある、java/io/FileSystem.java

    public static native FileSystem getFileSystem();
native が出てきたので、JVMのコード FileSystem_md.c

JVMコードの j2se/src/solaris/native/java/io/FileSystem_md.c

JNIEXPORT jobject JNICALL
Java_java_io_FileSystem_getFileSystem(JNIEnv *env, jclass ignored)
{
    return JNU_NewObjectByName(env, "java/io/UnixFileSystem", "()V");
}
FileSystem の実装は java.io.UnixFileSystem

JVMコードの j2se/src/solaris/classes/java/io/UnixFileSystem.java

    public boolean rename(File f1, File f2) {
        // Keep canonicalization caches in sync after file deletion
        // and renaming operations. Could be more clever than this
        // (i.e., only remove/update affected entries) but probably
        // not worth it since these entries expire after 30 seconds
        // anyway.
        cache.clear();
        javaHomePrefixCache.clear();
        return rename0(f1, f2);
    }
    private native boolean rename0(File f1, File f2);
再びネイティブコード UnixFileSystem_md.c

JVMコードの j2se/src/solaris/native/java/io/UnixFileSystem_md.c

Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
                                    jobject from, jobject to)
{
    jboolean rv = JNI_FALSE;

    WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
        WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
            if (rename(fromPath, toPath) == 0) {
                rv = JNI_TRUE;
            }
        } END_PLATFORM_STRING(env, toPath);
    } END_PLATFORM_STRING(env, fromPath);
    return rv;
}

この中にある rename(fromPath, toPath) は、jni.hの中にstdio.h からきてる。rename(2)は不可分にファイルのリネームを行う(断言してるソースがないけど指定されたページまたはファイルは存在しませんを参照。後Oracle Documentationとか404 - エラー: 404とか)ので、java.io.File#renameTo(File)は不可分にファイルのリネームを行う。


JVMのコード:。 参照した時点では 6u18-eaだった。