classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: FileChannel.map() for "short files"


From: Mark Wielaard
Subject: [cp-patches] FYI: FileChannel.map() for "short files"
Date: Mon, 09 Jan 2006 21:38:44 +0100

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  <address@hidden>

    * 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)

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]