415 } |
415 } |
416 |
416 |
417 /* |
417 /* |
418 * Class: sun_nio_ch_SctpChannelImpl |
418 * Class: sun_nio_ch_SctpChannelImpl |
419 * Method: receive0 |
419 * Method: receive0 |
420 * Signature: (ILsun/nio/ch/SctpResultContainer;JI)I |
420 * Signature: (ILsun/nio/ch/SctpResultContainer;JIZ)I |
421 */ |
421 */ |
422 JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_receive0 |
422 JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_receive0 |
423 (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj, |
423 (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj, |
424 jlong address, jint length) { |
424 jlong address, jint length, jboolean peek) { |
425 SOCKADDR sa; |
425 SOCKADDR sa; |
426 int sa_len = sizeof(sa); |
426 int sa_len = sizeof(sa); |
427 ssize_t rv = 0; |
427 ssize_t rv = 0; |
428 jlong *addr = jlong_to_ptr(address); |
428 jlong *addr = jlong_to_ptr(address); |
429 struct iovec iov[1]; |
429 struct iovec iov[1]; |
430 struct msghdr msg[1]; |
430 struct msghdr msg[1]; |
431 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))]; |
431 char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))]; |
|
432 int flags = peek == JNI_TRUE ? MSG_PEEK : 0; |
432 |
433 |
433 /* Set up the msghdr structure for receiving */ |
434 /* Set up the msghdr structure for receiving */ |
434 memset(msg, 0, sizeof (*msg)); |
435 memset(msg, 0, sizeof (*msg)); |
435 msg->msg_name = &sa; |
436 msg->msg_name = &sa; |
436 msg->msg_namelen = sa_len; |
437 msg->msg_namelen = sa_len; |
441 msg->msg_control = cbuf; |
442 msg->msg_control = cbuf; |
442 msg->msg_controllen = sizeof(cbuf); |
443 msg->msg_controllen = sizeof(cbuf); |
443 msg->msg_flags = 0; |
444 msg->msg_flags = 0; |
444 |
445 |
445 do { |
446 do { |
446 if ((rv = recvmsg(fd, msg, 0)) < 0) { |
447 if ((rv = recvmsg(fd, msg, flags)) < 0) { |
447 if (errno == EWOULDBLOCK) { |
448 if (errno == EWOULDBLOCK) { |
448 return IOS_UNAVAILABLE; |
449 return IOS_UNAVAILABLE; |
449 } else if (errno == EINTR) { |
450 } else if (errno == EINTR) { |
450 return IOS_INTERRUPTED; |
451 return IOS_INTERRUPTED; |
451 |
452 |
471 char buf[NOTIFICATION_BUFFER_SIZE]; |
472 char buf[NOTIFICATION_BUFFER_SIZE]; |
472 int rvSAVE = rv; |
473 int rvSAVE = rv; |
473 memcpy(buf, addr, rv); |
474 memcpy(buf, addr, rv); |
474 iov->iov_base = buf + rv; |
475 iov->iov_base = buf + rv; |
475 iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv; |
476 iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv; |
476 if ((rv = recvmsg(fd, msg, 0)) < 0) { |
477 if ((rv = recvmsg(fd, msg, flags)) < 0) { |
477 handleSocketError(env, errno); |
478 handleSocketError(env, errno); |
478 return 0; |
479 return 0; |
479 } |
480 } |
480 bufp = buf; |
481 bufp = buf; |
481 rv += rvSAVE; |
482 rv += rvSAVE; |