jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
changeset 2057 3acf8e5e2ca0
parent 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
     1 /*
     1 /*
     2  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    32 #include "nio_util.h"
    32 #include "nio_util.h"
    33 #include "sun_nio_ch_FileChannelImpl.h"
    33 #include "sun_nio_ch_FileChannelImpl.h"
    34 
    34 
    35 static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */
    35 static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */
    36 
    36 
    37 
       
    38 /* false for 95/98/ME, true for NT/W2K */
       
    39 static jboolean onNT = JNI_FALSE;
       
    40 
       
    41 /**************************************************************
    37 /**************************************************************
    42  * static method to store field ID's in initializers
    38  * static method to store field ID's in initializers
    43  * and retrieve the allocation granularity
    39  * and retrieve the allocation granularity
    44  */
    40  */
    45 JNIEXPORT jlong JNICALL
    41 JNIEXPORT jlong JNICALL
    46 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    42 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    47 {
    43 {
    48     SYSTEM_INFO si;
    44     SYSTEM_INFO si;
    49     jint align;
    45     jint align;
    50     OSVERSIONINFO ver;
       
    51     GetSystemInfo(&si);
    46     GetSystemInfo(&si);
    52     align = si.dwAllocationGranularity;
    47     align = si.dwAllocationGranularity;
    53     chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
    48     chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
    54     ver.dwOSVersionInfoSize = sizeof(ver);
       
    55     GetVersionEx(&ver);
       
    56     if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
       
    57         onNT = JNI_TRUE;
       
    58     }
       
    59     return align;
    49     return align;
    60 }
    50 }
    61 
    51 
    62 
    52 
    63 /**************************************************************
    53 /**************************************************************
   144         return IOS_THROWN;
   134         return IOS_THROWN;
   145     }
   135     }
   146     return 0;
   136     return 0;
   147 }
   137 }
   148 
   138 
   149 JNIEXPORT jint JNICALL
       
   150 Java_sun_nio_ch_FileChannelImpl_truncate0(JNIEnv *env, jobject this,
       
   151                                     jobject fdo, jlong size)
       
   152 {
       
   153     DWORD lowPos = 0;
       
   154     long highPos = 0;
       
   155     BOOL result = 0;
       
   156     HANDLE h = (HANDLE)(handleval(env, fdo));
       
   157 
       
   158     lowPos = (DWORD)size;
       
   159     highPos = (long)(size >> 32);
       
   160     lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
       
   161     if (lowPos == ((DWORD)-1)) {
       
   162         if (GetLastError() != ERROR_SUCCESS) {
       
   163             JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
       
   164             return IOS_THROWN;
       
   165         }
       
   166     }
       
   167     result = SetEndOfFile(h);
       
   168     if (result == 0) {
       
   169         JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
       
   170         return IOS_THROWN;
       
   171     }
       
   172     return 0;
       
   173 }
       
   174 
       
   175 
       
   176 JNIEXPORT jint JNICALL
       
   177 Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this,
       
   178                                     jobject fdo, jboolean md)
       
   179 {
       
   180     int result = 0;
       
   181     HANDLE h = (HANDLE)(handleval(env, fdo));
       
   182 
       
   183     if (h != INVALID_HANDLE_VALUE) {
       
   184         result = FlushFileBuffers(h);
       
   185         if (result == 0) {
       
   186             int error = GetLastError();
       
   187             if (error != ERROR_ACCESS_DENIED) {
       
   188                 JNU_ThrowIOExceptionWithLastError(env, "Force failed");
       
   189                 return IOS_THROWN;
       
   190             }
       
   191         }
       
   192     } else {
       
   193         JNU_ThrowIOExceptionWithLastError(env, "Force failed");
       
   194         return IOS_THROWN;
       
   195     }
       
   196     return 0;
       
   197 }
       
   198 
       
   199 JNIEXPORT jlong JNICALL
   139 JNIEXPORT jlong JNICALL
   200 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
   140 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
   201                                           jobject fdo, jlong offset)
   141                                           jobject fdo, jlong offset)
   202 {
   142 {
   203     DWORD lowPos = 0;
   143     DWORD lowPos = 0;
   218         }
   158         }
   219     }
   159     }
   220     return (((jlong)highPos) << 32) | lowPos;
   160     return (((jlong)highPos) << 32) | lowPos;
   221 }
   161 }
   222 
   162 
   223 JNIEXPORT jlong JNICALL
       
   224 Java_sun_nio_ch_FileChannelImpl_size0(JNIEnv *env, jobject this, jobject fdo)
       
   225 {
       
   226     DWORD sizeLow = 0;
       
   227     DWORD sizeHigh = 0;
       
   228     HANDLE h = (HANDLE)(handleval(env, fdo));
       
   229 
       
   230     sizeLow = GetFileSize(h, &sizeHigh);
       
   231     if (sizeLow == ((DWORD)-1)) {
       
   232         if (GetLastError() != ERROR_SUCCESS) {
       
   233             JNU_ThrowIOExceptionWithLastError(env, "Size failed");
       
   234             return IOS_THROWN;
       
   235         }
       
   236     }
       
   237     return (((jlong)sizeHigh) << 32) | sizeLow;
       
   238 }
       
   239 
       
   240 JNIEXPORT void JNICALL
   163 JNIEXPORT void JNICALL
   241 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
   164 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
   242 {
   165 {
   243     HANDLE h = (HANDLE)(handleval(env, fdo));
   166     HANDLE h = (HANDLE)(handleval(env, fdo));
   244     if (h != INVALID_HANDLE_VALUE) {
   167     if (h != INVALID_HANDLE_VALUE) {
   255                                             jlong position, jlong count,
   178                                             jlong position, jlong count,
   256                                             jint dstFD)
   179                                             jint dstFD)
   257 {
   180 {
   258     return IOS_UNSUPPORTED;
   181     return IOS_UNSUPPORTED;
   259 }
   182 }
   260 
       
   261 JNIEXPORT jint JNICALL
       
   262 Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
       
   263                                       jboolean block, jlong pos, jlong size,
       
   264                                       jboolean shared)
       
   265 {
       
   266     HANDLE h = (HANDLE)(handleval(env, fdo));
       
   267     DWORD lowPos = (DWORD)pos;
       
   268     long highPos = (long)(pos >> 32);
       
   269     DWORD lowNumBytes = (DWORD)size;
       
   270     DWORD highNumBytes = (DWORD)(size >> 32);
       
   271     jint result = 0;
       
   272     if (onNT) {
       
   273         DWORD flags = 0;
       
   274         OVERLAPPED o;
       
   275         o.hEvent = 0;
       
   276         o.Offset = lowPos;
       
   277         o.OffsetHigh = highPos;
       
   278         if (block == JNI_FALSE) {
       
   279             flags |= LOCKFILE_FAIL_IMMEDIATELY;
       
   280         }
       
   281         if (shared == JNI_FALSE) {
       
   282             flags |= LOCKFILE_EXCLUSIVE_LOCK;
       
   283         }
       
   284         result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
       
   285         if (result == 0) {
       
   286             int error = GetLastError();
       
   287             if (error != ERROR_LOCK_VIOLATION) {
       
   288                 JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
       
   289                 return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   290             }
       
   291             if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
       
   292                 return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   293             }
       
   294             JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
       
   295             return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   296         }
       
   297         return sun_nio_ch_FileChannelImpl_LOCKED;
       
   298     } else {
       
   299         for(;;) {
       
   300             if (size > 0x7fffffff) {
       
   301                 size = 0x7fffffff;
       
   302             }
       
   303             lowNumBytes = (DWORD)size;
       
   304             highNumBytes = 0;
       
   305             result = LockFile(h, lowPos, highPos, lowNumBytes, highNumBytes);
       
   306             if (result != 0) {
       
   307                 if (shared == JNI_TRUE) {
       
   308                     return sun_nio_ch_FileChannelImpl_RET_EX_LOCK;
       
   309                 } else {
       
   310                     return sun_nio_ch_FileChannelImpl_LOCKED;
       
   311                 }
       
   312             } else {
       
   313                 int error = GetLastError();
       
   314                 if (error != ERROR_LOCK_VIOLATION) {
       
   315                     JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
       
   316                     return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   317                 }
       
   318                 if (block == JNI_FALSE) {
       
   319                     return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   320                 }
       
   321             }
       
   322             Sleep(100);
       
   323         }
       
   324     }
       
   325     return sun_nio_ch_FileChannelImpl_NO_LOCK;
       
   326 }
       
   327 
       
   328 JNIEXPORT void JNICALL
       
   329 Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this,
       
   330                                         jobject fdo, jlong pos, jlong size)
       
   331 {
       
   332     HANDLE h = (HANDLE)(handleval(env, fdo));
       
   333     DWORD lowPos = (DWORD)pos;
       
   334     long highPos = (long)(pos >> 32);
       
   335     DWORD lowNumBytes = (DWORD)size;
       
   336     DWORD highNumBytes = (DWORD)(size >> 32);
       
   337     jint result = 0;
       
   338     if (onNT) {
       
   339         OVERLAPPED o;
       
   340         o.hEvent = 0;
       
   341         o.Offset = lowPos;
       
   342         o.OffsetHigh = highPos;
       
   343         result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);
       
   344     } else {
       
   345         if (size > 0x7fffffff) {
       
   346             size = 0x7fffffff;
       
   347         }
       
   348         lowNumBytes = (DWORD)size;
       
   349         highNumBytes = 0;
       
   350         result = UnlockFile(h, lowPos, highPos, lowNumBytes, highNumBytes);
       
   351     }
       
   352     if (result == 0) {
       
   353         JNU_ThrowIOExceptionWithLastError(env, "Release failed");
       
   354     }
       
   355 }