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);