JNIEXPORT jlong JNICALL Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { jint fd = fdval(env, fdo); struct iovec *iov = (struct iovec *)jlong_to_ptr(address); struct msghdr m; ssize_t result = 0; if (len > 16) { len = 16; } m.msg_name = NULL; m.msg_namelen = 0; m.msg_iov = iov; m.msg_iovlen = len; #ifdef __solaris__ m.msg_accrights = NULL; m.msg_accrightslen = 0; #endif #ifdef __linux__ m.msg_control = NULL; m.msg_controllen = 0; #endif result = sendmsg(fd, &m, 0); if (result < 0 && errno == ECONNREFUSED) { JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0); return -2; } return convertLongReturnVal(env, (jlong)result, JNI_FALSE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { /* set up */ int i = 0; DWORD read = 0; DWORD flags = 0; jint fd = fdval(env, fdo); struct iovec *iovp = (struct iovec *)address; WSABUF *bufs = malloc(len * sizeof(WSABUF)); jint rem = MAX_BUFFER_SIZE; if (bufs == 0) { JNU_ThrowOutOfMemoryError(env, 0); return IOS_THROWN; } /* copy iovec into WSABUF */ for(i=0; i<len; i++) { jint iov_len = iovp[i].iov_len; if (iov_len > rem) iov_len = rem; bufs[i].buf = (char *)iovp[i].iov_base; bufs[i].len = (u_long)iov_len; rem -= iov_len; if (rem == 0) { len = i+1; break; } } /* read into the buffers */ i = WSARecv((SOCKET)fd, /* Socket */ bufs, /* pointers to the buffers */ (DWORD)len, /* number of buffers to process */ &read, /* receives number of bytes read */ &flags, /* no flags */ 0, /* no overlapped sockets */ 0); /* no completion routine */ /* clean up */ free(bufs); if (i != 0) { int theErr = (jint)WSAGetLastError(); if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; } JNU_ThrowIOExceptionWithLastError(env, "Vector read failed"); return IOS_THROWN; } return convertLongReturnVal(env, (jlong)read, JNI_TRUE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcher_writev0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { jint fd = fdval(env, fdo); struct iovec *iov = (struct iovec *)jlong_to_ptr(address); if (len > 16) { len = 16; } return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { DWORD read = 0; BOOL result = 0; jlong totalRead = 0; LPVOID loc; int i = 0; DWORD num = 0; struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address); HANDLE h = (HANDLE)(handleval(env, fdo)); if (h == INVALID_HANDLE_VALUE) { JNU_ThrowIOExceptionWithLastError(env, "Invalid handle"); return IOS_THROWN; } for(i=0; i<len; i++) { loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base); num = iovecp[i].iov_len; result = ReadFile(h, /* File handle to read */ loc, /* address to put data */ num, /* number of bytes to read */ &read, /* number of bytes read */ NULL); /* no overlapped struct */ if (read > 0) { totalRead += read; } if (read < num) { break; } } if (result == 0) { int error = GetLastError(); if (error == ERROR_BROKEN_PIPE) { return IOS_EOF; } if (error == ERROR_NO_DATA) { return IOS_UNAVAILABLE; } JNU_ThrowIOExceptionWithLastError(env, "Read failed"); return IOS_THROWN; } return convertLongReturnVal(env, totalRead, JNI_TRUE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len, jboolean append) { BOOL result = 0; DWORD written = 0; HANDLE h = (HANDLE)(handleval(env, fdo)); jlong totalWritten = 0; if (h != INVALID_HANDLE_VALUE) { LPVOID loc; int i = 0; DWORD num = 0; struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address); OVERLAPPED ov; LPOVERLAPPED lpOv; if (append == JNI_TRUE) { ov.Offset = (DWORD)0xFFFFFFFF; ov.OffsetHigh = (DWORD)0xFFFFFFFF; ov.hEvent = NULL; lpOv = &ov; } else { lpOv = NULL; } for(i=0; i<len; i++) { loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base); num = iovecp[i].iov_len; result = WriteFile(h, /* File handle to write */ loc, /* pointers to the buffers */ num, /* number of bytes to write */ &written,/* receives number of bytes written */ lpOv); /* overlapped struct */ if (written > 0) { totalWritten += written; } if (written < num) { break; } } } if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { JNU_ThrowIOExceptionWithLastError(env, "Write failed"); } return convertLongReturnVal(env, totalWritten, JNI_FALSE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { /* set up */ int i = 0; DWORD read = 0; DWORD flags = 0; jint fd = fdval(env, fdo); struct iovec *iovp = (struct iovec *)address; WSABUF *bufs = malloc(len * sizeof(WSABUF)); /* copy iovec into WSABUF */ for(i=0; i<len; i++) { bufs[i].buf = (char *)iovp[i].iov_base; bufs[i].len = (u_long)iovp[i].iov_len; } /* read into the buffers */ i = WSARecv((SOCKET)fd, /* Socket */ bufs, /* pointers to the buffers */ (DWORD)len, /* number of buffers to process */ &read, /* receives number of bytes read */ &flags, /* no flags */ 0, /* no overlapped sockets */ 0); /* no completion routine */ /* clean up */ free(bufs); if (i != 0) { int theErr = (jint)WSAGetLastError(); if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; } if (theErr == WSAECONNRESET) { purgeOutstandingICMP(env, clazz, fd); JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0); return IOS_THROWN; } JNU_ThrowIOExceptionWithLastError(env, "Write failed"); return IOS_THROWN; } return convertLongReturnVal(env, (jlong)read, JNI_TRUE); }
JNIEXPORT jlong JNICALL Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz, jobject fdo, jlong address, jint len) { /* set up */ int next_index, next_offset, ret=0; DWORD written = 0; jint fd = fdval(env, fdo); struct iovec *iovp = (struct iovec *)address; WSABUF *bufs = malloc(len * sizeof(WSABUF)); jlong count = 0; if (bufs == 0) { JNU_ThrowOutOfMemoryError(env, 0); return IOS_THROWN; } // next buffer and offset to consume next_index = 0; next_offset = 0; while (next_index < len) { DWORD buf_count = 0; /* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */ jint rem = MAX_BUFFER_SIZE; while (next_index < len && rem > 0) { jint iov_len = iovp[next_index].iov_len - next_offset; char* ptr = (char *)iovp[next_index].iov_base; ptr += next_offset; if (iov_len > rem) { iov_len = rem; next_offset += rem; } else { next_index ++; next_offset = 0; } bufs[buf_count].buf = ptr; bufs[buf_count].len = (u_long)iov_len; buf_count++; rem -= iov_len; } /* write the buffers */ ret = WSASend((SOCKET)fd, /* Socket */ bufs, /* pointers to the buffers */ buf_count, /* number of buffers to process */ &written, /* receives number of bytes written */ 0, /* no flags */ 0, /* no overlapped sockets */ 0); /* no completion routine */ if (ret == SOCKET_ERROR) { break; } count += written; } /* clean up */ free(bufs); if (ret == SOCKET_ERROR && count == 0) { int theErr = (jint)WSAGetLastError(); if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; } JNU_ThrowIOExceptionWithLastError(env, "Vector write failed"); return IOS_THROWN; } return convertLongReturnVal(env, count, JNI_FALSE); }