src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
author ohair
Tue May 25 15:58:33 2010 -0700 (24 months ago)
changeset 2361 00cd9dc3c2b5
parent 895f06f30b29f36
permissions -rw-r--r--
6943119: Rebrand source copyright notices
Reviewed-by: darcy, weijun
        1 /*
        2  * Copyright (c) 2000, 2009, Oracle and/or its affiliates. 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.  Oracle designates this
        8  * particular file as subject to the "Classpath" exception as provided
        9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       22  * or visit www.oracle.com if you need additional information or have any
       23  * 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 }