Print this page
OS-4602 lxbrand support recvmsg(MSG_PEEK|MSG_TRUNC) behavior
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
@@ -668,14 +668,19 @@
boolean_t partial_read;
boolean_t reset_atmark = B_FALSE;
int more = 0;
int error;
ssize_t oobmark;
+ ssize_t copied = 0;
sodirect_t *sodp = so->so_direct;
+ xuio_t *xuio = NULL;
partial_read = B_FALSE;
*mctlp = NULL;
+ if ((uiop->uio_extflg & UIO_XUIO) != 0) {
+ xuio = (xuio_t *)uiop;
+ }
again:
mutex_enter(&so->so_lock);
again1:
#ifdef DEBUG
if (so_debug_length) {
@@ -782,12 +787,10 @@
/*
* Now process DATA blocks, if any. Note that for sodirect
* enabled socket, uio_resid can be 0.
*/
if (uiop->uio_resid >= 0) {
- ssize_t copied = 0;
-
if (sodp != NULL && (DB_FLAGS(mp) & DBLK_UIOA)) {
mutex_enter(&so->so_lock);
ASSERT(uiop == (uio_t *)&sodp->sod_uioa);
copied = sod_uioa_mblk(so, mp);
if (copied > 0)
@@ -841,10 +844,22 @@
rvalp->r_val2 = so_check_flow_control(so);
}
}
if (mp != NULL) { /* more data blocks in msg */
more |= MOREDATA;
+
+ /*
+ * If requested, tally up remaining data along with the
+ * amount already copied.
+ */
+ if (xuio != NULL &&
+ xuio->xu_type == UIOTYPE_PEEKSIZE) {
+ xuio->xu_ext.xu_ps.xu_ps_set = B_TRUE;
+ xuio->xu_ext.xu_ps.xu_ps_size =
+ copied + msgdsize(mp);
+ }
+
if ((flags & (MSG_PEEK|MSG_TRUNC))) {
if (flags & MSG_PEEK) {
freemsg(mp);
} else {
unsigned int msize = msgdsize(mp);