jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
changeset 2057 3acf8e5e2ca0
parent 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
       
     1 /*
       
     2  * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 #include "jni.h"
       
    27 #include "jni_util.h"
       
    28 #include "jvm.h"
       
    29 #include "jlong.h"
       
    30 #include "sun_nio_ch_FileDispatcherImpl.h"
       
    31 #include "java_lang_Long.h"
       
    32 #include <sys/types.h>
       
    33 #include <sys/socket.h>
       
    34 #include <fcntl.h>
       
    35 #include <sys/uio.h>
       
    36 #include "nio.h"
       
    37 #include "nio_util.h"
       
    38 
       
    39 
       
    40 static int preCloseFD = -1;     /* File descriptor to which we dup other fd's
       
    41                                    before closing them for real */
       
    42 
       
    43 
       
    44 JNIEXPORT void JNICALL
       
    45 Java_sun_nio_ch_FileDispatcherImpl_init(JNIEnv *env, jclass cl)
       
    46 {
       
    47     int sp[2];
       
    48     if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
       
    49         JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
       
    50         return;
       
    51     }
       
    52     preCloseFD = sp[0];
       
    53     close(sp[1]);
       
    54 }
       
    55 
       
    56 JNIEXPORT jint JNICALL
       
    57 Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
       
    58                              jobject fdo, jlong address, jint len)
       
    59 {
       
    60     jint fd = fdval(env, fdo);
       
    61     void *buf = (void *)jlong_to_ptr(address);
       
    62 
       
    63     return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);
       
    64 }
       
    65 
       
    66 JNIEXPORT jint JNICALL
       
    67 Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
       
    68                             jlong address, jint len, jlong offset)
       
    69 {
       
    70     jint fd = fdval(env, fdo);
       
    71     void *buf = (void *)jlong_to_ptr(address);
       
    72 
       
    73     return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);
       
    74 }
       
    75 
       
    76 JNIEXPORT jlong JNICALL
       
    77 Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz,
       
    78                               jobject fdo, jlong address, jint len)
       
    79 {
       
    80     jint fd = fdval(env, fdo);
       
    81     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
       
    82     if (len > 16) {
       
    83         len = 16;
       
    84     }
       
    85     return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
       
    86 }
       
    87 
       
    88 JNIEXPORT jint JNICALL
       
    89 Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,
       
    90                               jobject fdo, jlong address, jint len)
       
    91 {
       
    92     jint fd = fdval(env, fdo);
       
    93     void *buf = (void *)jlong_to_ptr(address);
       
    94 
       
    95     return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);
       
    96 }
       
    97 
       
    98 JNIEXPORT jint JNICALL
       
    99 Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
       
   100                             jlong address, jint len, jlong offset)
       
   101 {
       
   102     jint fd = fdval(env, fdo);
       
   103     void *buf = (void *)jlong_to_ptr(address);
       
   104 
       
   105     return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);
       
   106 }
       
   107 
       
   108 JNIEXPORT jlong JNICALL
       
   109 Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz,
       
   110                                        jobject fdo, jlong address, jint len)
       
   111 {
       
   112     jint fd = fdval(env, fdo);
       
   113     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
       
   114     if (len > 16) {
       
   115         len = 16;
       
   116     }
       
   117     return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
       
   118 }
       
   119 
       
   120 static jlong
       
   121 handle(JNIEnv *env, jlong rv, char *msg)
       
   122 {
       
   123     if (rv >= 0)
       
   124         return rv;
       
   125     if (errno == EINTR)
       
   126         return IOS_INTERRUPTED;
       
   127     JNU_ThrowIOExceptionWithLastError(env, msg);
       
   128     return IOS_THROWN;
       
   129 }
       
   130 
       
   131 JNIEXPORT jint JNICALL
       
   132 Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
       
   133                                           jobject fdo, jboolean md)
       
   134 {
       
   135     jint fd = fdval(env, fdo);
       
   136     int result = 0;
       
   137 
       
   138     if (md == JNI_FALSE) {
       
   139         result = fdatasync(fd);
       
   140     } else {
       
   141         result = fsync(fd);
       
   142     }
       
   143     return handle(env, result, "Force failed");
       
   144 }
       
   145 
       
   146 JNIEXPORT jint JNICALL
       
   147 Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
       
   148                                              jobject fdo, jlong size)
       
   149 {
       
   150     return handle(env,
       
   151                   ftruncate64(fdval(env, fdo), size),
       
   152                   "Truncation failed");
       
   153 }
       
   154 
       
   155 JNIEXPORT jlong JNICALL
       
   156 Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
       
   157 {
       
   158     struct stat64 fbuf;
       
   159 
       
   160     if (fstat64(fdval(env, fdo), &fbuf) < 0)
       
   161         return handle(env, -1, "Size failed");
       
   162     return fbuf.st_size;
       
   163 }
       
   164 
       
   165 JNIEXPORT jint JNICALL
       
   166 Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
       
   167                                       jboolean block, jlong pos, jlong size,
       
   168                                       jboolean shared)
       
   169 {
       
   170     jint fd = fdval(env, fdo);
       
   171     jint lockResult = 0;
       
   172     int cmd = 0;
       
   173     struct flock64 fl;
       
   174 
       
   175     fl.l_whence = SEEK_SET;
       
   176     if (size == (jlong)java_lang_Long_MAX_VALUE) {
       
   177         fl.l_len = (off64_t)0;
       
   178     } else {
       
   179         fl.l_len = (off64_t)size;
       
   180     }
       
   181     fl.l_start = (off64_t)pos;
       
   182     if (shared == JNI_TRUE) {
       
   183         fl.l_type = F_RDLCK;
       
   184     } else {
       
   185         fl.l_type = F_WRLCK;
       
   186     }
       
   187     if (block == JNI_TRUE) {
       
   188         cmd = F_SETLKW64;
       
   189     } else {
       
   190         cmd = F_SETLK64;
       
   191     }
       
   192     lockResult = fcntl(fd, cmd, &fl);
       
   193     if (lockResult < 0) {
       
   194         if ((cmd == F_SETLK64) && (errno == EAGAIN))
       
   195             return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
       
   196         if (errno == EINTR)
       
   197             return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;
       
   198         JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
       
   199     }
       
   200     return 0;
       
   201 }
       
   202 
       
   203 JNIEXPORT void JNICALL
       
   204 Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
       
   205                                          jobject fdo, jlong pos, jlong size)
       
   206 {
       
   207     jint fd = fdval(env, fdo);
       
   208     jint lockResult = 0;
       
   209     struct flock64 fl;
       
   210     int cmd = F_SETLK64;
       
   211 
       
   212     fl.l_whence = SEEK_SET;
       
   213     if (size == (jlong)java_lang_Long_MAX_VALUE) {
       
   214         fl.l_len = (off64_t)0;
       
   215     } else {
       
   216         fl.l_len = (off64_t)size;
       
   217     }
       
   218     fl.l_start = (off64_t)pos;
       
   219     fl.l_type = F_UNLCK;
       
   220     lockResult = fcntl(fd, cmd, &fl);
       
   221     if (lockResult < 0) {
       
   222         JNU_ThrowIOExceptionWithLastError(env, "Release failed");
       
   223     }
       
   224 }
       
   225 
       
   226 
       
   227 static void closeFileDescriptor(JNIEnv *env, int fd) {
       
   228     if (fd != -1) {
       
   229         int result = close(fd);
       
   230         if (result < 0)
       
   231             JNU_ThrowIOExceptionWithLastError(env, "Close failed");
       
   232     }
       
   233 }
       
   234 
       
   235 JNIEXPORT void JNICALL
       
   236 Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
       
   237 {
       
   238     jint fd = fdval(env, fdo);
       
   239     closeFileDescriptor(env, fd);
       
   240 }
       
   241 
       
   242 JNIEXPORT void JNICALL
       
   243 Java_sun_nio_ch_FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
       
   244 {
       
   245     jint fd = fdval(env, fdo);
       
   246     if (preCloseFD >= 0) {
       
   247         if (dup2(preCloseFD, fd) < 0)
       
   248             JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
       
   249     }
       
   250 }
       
   251 
       
   252 JNIEXPORT void JNICALL
       
   253 Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
       
   254 {
       
   255     closeFileDescriptor(env, fd);
       
   256 }