1 /* 2 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2012 SAP AG. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 #include "jni.h" 28 #include "jni_util.h" 29 #include "jvm.h" 30 #include "jlong.h" 31 #include "nio_util.h" 32 33 #include "sun_nio_ch_AixPollPort.h" 34 35 #include <unistd.h> 36 #include <sys/types.h> 37 #include <sys/socket.h> 38 #include <sys/poll.h> 39 /* pollset may not be available at build time */ 40 #if 0 41 #include <sys/pollset.h> 42 #else 43 typedef int pollset_t; 44 struct poll_ctl { 45 short cmd; 46 short events; 47 int fd; 48 }; 49 typedef pollset_t pollset_create_func(int maxfd); 50 typedef int pollset_destroy_func(pollset_t ps); 51 typedef int pollset_ctl_func(pollset_t ps, struct poll_ctl *pollctl_array, int array_length); 52 typedef int pollset_poll_func(pollset_t ps, struct pollfd *polldata_array, int array_length, int timeout); 53 static pollset_create_func* _pollset_create = NULL; 54 static pollset_destroy_func* _pollset_destroy = NULL; 55 static pollset_ctl_func* _pollset_ctl = NULL; 56 static pollset_poll_func* _pollset_poll = NULL; 57 #include <dlfcn.h> 58 /* RTLD_DEFAULT is not available on AIX 5.2 */ 59 #ifndef RTLD_DEFAULT 60 #define RTLD_DEFAULT ((void *)(-1)) 61 #endif 62 #endif /* pollset */ 63 #include <fcntl.h> 64 #include <stddef.h> 65 66 JNIEXPORT void JNICALL 67 Java_sun_nio_ch_AixPollPort_init(JNIEnv* env, jclass this) { 68 _pollset_create = (pollset_create_func*) dlsym(RTLD_DEFAULT, "pollset_create"); 69 _pollset_destroy = (pollset_destroy_func*) dlsym(RTLD_DEFAULT, "pollset_destroy"); 70 _pollset_ctl = (pollset_ctl_func*) dlsym(RTLD_DEFAULT, "pollset_ctl"); 71 _pollset_poll = (pollset_poll_func*) dlsym(RTLD_DEFAULT, "pollset_poll"); 72 if (_pollset_create == NULL || _pollset_destroy == NULL || 73 _pollset_ctl == NULL || _pollset_poll == NULL) { 74 JNU_ThrowInternalError(env, "unable to get address of pollset functions"); 75 } 76 } 77 78 JNIEXPORT jint JNICALL 79 Java_sun_nio_ch_AixPollPort_eventSize(JNIEnv* env, jclass this) { 80 return sizeof(struct pollfd); 81 } 82 83 JNIEXPORT jint JNICALL 84 Java_sun_nio_ch_AixPollPort_eventsOffset(JNIEnv* env, jclass this) { 85 return offsetof(struct pollfd, events); 86 } 87 88 JNIEXPORT jint JNICALL 89 Java_sun_nio_ch_AixPollPort_reventsOffset(JNIEnv* env, jclass this) { 90 return offsetof(struct pollfd, revents); 91 } 92 93 JNIEXPORT jint JNICALL 94 Java_sun_nio_ch_AixPollPort_fdOffset(JNIEnv* env, jclass this) { 95 return offsetof(struct pollfd, fd); 96 } 97 98 JNIEXPORT jint JNICALL 99 Java_sun_nio_ch_AixPollPort_pollsetCreate(JNIEnv *env, jclass c) { 100 /* pollset_create can take the maximum number of fds, but we 101 * cannot predict this number so we leave it at OPEN_MAX. */ 102 pollset_t ps = _pollset_create(-1); 103 if (ps < 0) { 104 JNU_ThrowIOExceptionWithLastError(env, "pollset_create failed"); 105 } 106 return (int)ps; 107 } 108 109 JNIEXPORT jint JNICALL 110 Java_sun_nio_ch_AixPollPort_pollsetCtl(JNIEnv *env, jclass c, jint ps, 111 jint opcode, jint fd, jint events) { 112 struct poll_ctl event; 113 int res; 114 115 event.cmd = opcode; 116 event.events = events; 117 event.fd = fd; 118 119 RESTARTABLE(_pollset_ctl((pollset_t)ps, &event, 1 /* length */), res); 120 121 return (res == 0) ? 0 : errno; 122 } 123 124 JNIEXPORT jint JNICALL 125 Java_sun_nio_ch_AixPollPort_pollsetPoll(JNIEnv *env, jclass c, 126 jint ps, jlong address, jint numfds) { 127 struct pollfd *events = jlong_to_ptr(address); 128 int res; 129 130 RESTARTABLE(_pollset_poll(ps, events, numfds, -1), res); 131 if (res < 0) { 132 JNU_ThrowIOExceptionWithLastError(env, "pollset_poll failed"); 133 } 134 return res; 135 } 136 137 JNIEXPORT void JNICALL 138 Java_sun_nio_ch_AixPollPort_pollsetDestroy(JNIEnv *env, jclass c, jint ps) { 139 int res; 140 RESTARTABLE(_pollset_destroy((pollset_t)ps), res); 141 } 142 143 JNIEXPORT void JNICALL 144 Java_sun_nio_ch_AixPollPort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) { 145 int sp[2]; 146 if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) { 147 JNU_ThrowIOExceptionWithLastError(env, "socketpair failed"); 148 } else { 149 jint res[2]; 150 res[0] = (jint)sp[0]; 151 res[1] = (jint)sp[1]; 152 (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]); 153 } 154 } 155 156 JNIEXPORT void JNICALL 157 Java_sun_nio_ch_AixPollPort_interrupt(JNIEnv *env, jclass c, jint fd) { 158 int res; 159 int buf[1]; 160 buf[0] = 1; 161 RESTARTABLE(write(fd, buf, 1), res); 162 if (res < 0) { 163 JNU_ThrowIOExceptionWithLastError(env, "write failed"); 164 } 165 } 166 167 JNIEXPORT void JNICALL 168 Java_sun_nio_ch_AixPollPort_drain1(JNIEnv *env, jclass cl, jint fd) { 169 int res; 170 char buf[1]; 171 RESTARTABLE(read(fd, buf, 1), res); 172 if (res < 0) { 173 JNU_ThrowIOExceptionWithLastError(env, "drain1 failed"); 174 } 175 } 176 177 JNIEXPORT void JNICALL 178 Java_sun_nio_ch_AixPollPort_close0(JNIEnv *env, jclass c, jint fd) { 179 int res; 180 RESTARTABLE(close(fd), res); 181 }