Is there any particular reason for having native implementations of open() in both gnu_java_nio_VMChannel.c and gnu_java_nio_FileChannelImpl.c? Aside from the bug in VMChannel, this duplication of open seemed to be the cause of the problem I saw.

Refactoring of FileChannelImpl.java lead to an (unintended?) switch between open() implementations and exposed the bug. I couldn't work out why there were two implementations in the first place.

--Steve

On 30/05/2007, at 9:12 PM, Andrew Haley wrote:

You know, the real cause of this bug was the obfuscated use of
conditional expressions.  This code does, I think, the same things,
but it's hard to be sure.

Andrew.


Index: gnu_java_nio_VMChannel.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/ gnu_java_nio_VMChannel.c,v
retrieving revision 1.19
diff -c -2 -p -w -r1.19 gnu_java_nio_VMChannel.c
*** gnu_java_nio_VMChannel.c    30 May 2007 09:56:57 -0000      1.19
--- gnu_java_nio_VMChannel.c    30 May 2007 11:04:57 -0000
*************** Java_gnu_java_nio_VMChannel_open (JNIEnv
*** 1667,1683 ****
    const char *npath;

!   if ((mode & CPNIO_READ) && (mode & CPNIO_WRITE))
!     nmode = O_RDWR;
!   else if (mode & CPNIO_WRITE)
!     nmode = O_WRONLY;
!   else
      nmode = O_RDONLY;

!   nmode = (nmode
!            | ((nmode == O_RDWR || nmode == O_WRONLY) ? O_CREAT : 0)
!            | ((mode & CPNIO_APPEND) ? O_APPEND :
!               ((nmode == O_WRONLY) ? O_TRUNC : 0))
!            | ((mode & CPNIO_EXCL) ? O_EXCL : 0)
!            | ((mode & CPNIO_SYNC) ? O_SYNC : 0));

    npath = JCL_jstring_to_cstring (env, path);
--- 1667,1700 ----
    const char *npath;

!   switch (mode & (CPNIO_READ | CPNIO_WRITE | CPNIO_APPEND))
!     {
!     case 0:
!     case CPNIO_APPEND: /* Is this legal?  */
!       break;
!     case CPNIO_WRITE:
!       nmode = O_WRONLY | O_CREAT | O_TRUNC;
!       break;
!     case CPNIO_WRITE | CPNIO_APPEND:
!       nmode = O_WRONLY | O_CREAT | O_APPEND;
!       break;
!     case CPNIO_READ:
        nmode = O_RDONLY;
+       break;
+     case CPNIO_READ | CPNIO_APPEND:
+       nmode = O_RDONLY | O_APPEND; /* Is this legal?  */
+       break;
+     case CPNIO_READ | CPNIO_WRITE:
+       nmode = O_RDWR | O_CREAT | O_TRUNC;
+       break;
+     case CPNIO_READ | CPNIO_WRITE | CPNIO_APPEND:
+       nmode = O_RDWR | O_CREAT | O_APPEND;
+       break;
+     }
+
+   if (mode & CPNIO_EXCL)
+     nmode |= O_EXCL;

!   if (mode & CPNIO_SYNC)
!     nmode |= O_SYNC;

    npath = JCL_jstring_to_cstring (env, path);


Reply via email to