Hi, If a file was "too short" for mmap we would happily "bus error" when someone tried to put() something in it. Although this is indeed "undefined behavior" it isn't the nicest way to handle this situation. This patch handles it by just making sure the file is big enough. It also fixes some other problems pointed out by Mauve.
2006-01-09 Mark Wielaard <[EMAIL PROTECTED]> * gnu/java/nio/channels/FileChannelImpl.java (map): Throw correct exception when channel is not readable or writable. * native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c (mapImpl): Add PROT_WRITE when mode == 'c' (MAP_PRIVATE). Make sure there is enough space to mmap. This makes all the Mauve tests that Jeroen made for this method (gnu.testlet.java.nio.channels.FileChannel.map) pass. Committed, Mark
Index: gnu/java/nio/channels/FileChannelImpl.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/nio/channels/FileChannelImpl.java,v retrieving revision 1.19 diff -u -r1.19 FileChannelImpl.java --- gnu/java/nio/channels/FileChannelImpl.java 11 Sep 2005 19:29:24 -0000 1.19 +++ gnu/java/nio/channels/FileChannelImpl.java 9 Jan 2006 20:38:33 -0000 @@ -1,5 +1,5 @@ /* FileChannelImpl.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -301,8 +301,10 @@ else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE) { nmode = mode == MapMode.READ_WRITE ? '+' : 'c'; - if ((this.mode & (READ|WRITE)) != (READ|WRITE)) + if ((this.mode & WRITE) != WRITE) throw new NonWritableChannelException(); + if ((this.mode & READ) != READ) + throw new NonReadableChannelException(); } else throw new IllegalArgumentException ("mode: " + mode); Index: native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c,v retrieving revision 1.27 diff -u -r1.27 gnu_java_nio_channels_FileChannelImpl.c --- native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c 3 Aug 2005 13:12:59 -0000 1.27 +++ native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c 9 Jan 2006 20:38:33 -0000 @@ -1,5 +1,5 @@ /* gnu_java_nio_channels_FileChannelImpl.c - - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -538,11 +538,27 @@ return NULL; } + fd = get_native_fd (env, obj); + prot = PROT_READ; - if (mode == '+') - prot |= PROT_WRITE; + if (mode == '+' || mode == 'c') + { + /* When writing we need to make sure the file is big enough, + otherwise the result of mmap is undefined. */ + jlong filesize; + filesize = Java_gnu_java_nio_channels_FileChannelImpl_size(env, obj); + if (filesize == -1) + return NULL; + if (position + size > filesize) + if (ftruncate(fd, position + size) == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + return NULL; + } + prot |= PROT_WRITE; + } + flags = (mode == 'c' ? MAP_PRIVATE : MAP_SHARED); - fd = get_native_fd (env, obj); p = mmap (NULL, (size_t) ALIGN_UP (size, pagesize), prot, flags, fd, ALIGN_DOWN (position, pagesize)); if (p == MAP_FAILED)
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches