func: static int do_sendv_recvv(int sockfd, struct iovec *iov, int len, int offset,
  
                            int do_sendv)
  
  {
  
      int ret, diff, iovlen;
  
      struct iovec *last_iov;
  
  
  
      /* last_iov is inclusive, so count from one.  */
  
      iovlen = 1;
  
      last_iov = iov;
  
      len += offset;
  
  
  
      while (last_iov->iov_len < len) {
  
          len -= last_iov->iov_len;
  
  
  
          last_iov++;
  
          iovlen++;
  
      }
  
  
  
      diff = last_iov->iov_len - len;
  
      last_iov->iov_len -= diff;
  
  
  
      while (iov->iov_len <= offset) {
  
          offset -= iov->iov_len;
  
  
  
          iov++;
  
          iovlen--;
  
      }
  
  
  
      iov->iov_base = (char *) iov->iov_base + offset;
  
      iov->iov_len -= offset;
  
  
  
      {
  
  #if defined CONFIG_IOVEC && defined CONFIG_POSIX
  
          struct msghdr msg;
  
          memset(&msg, 0, sizeof(msg));
  
          msg.msg_iov = iov;
  
          msg.msg_iovlen = iovlen;
  
  
  
          do {
  
              if (do_sendv) {
  
                  ret = sendmsg(sockfd, &msg, 0);
  
              } else {
  
                  ret = recvmsg(sockfd, &msg, 0);
  
              }
  
          } while (ret == -1 && errno == EINTR);
  
  #else
  
          struct iovec *p = iov;
  
          ret = 0;
  
          while (iovlen > 0) {
  
              int rc;
  
              if (do_sendv) {
  
                  rc = send(sockfd, p->iov_base, p->iov_len, 0);
  
              } else {
  
                  rc = qemu_recv(sockfd, p->iov_base, p->iov_len, 0);
  
              }
  
              if (rc == -1) {
  
                  if (errno == EINTR) {
  
                      continue;
  
                  }
  
                  if (ret == 0) {
  
                      ret = -1;
  
                  }
  
                  break;
  
              }
  
              if (rc == 0) {
  
                  break;
  
              }
  
              ret += rc;
  
              iovlen--, p++;
  
          }
  
  #endif
  
      }
  
  
  
      /* Undo the changes above */
  
      iov->iov_base = (char *) iov->iov_base - offset;
  
      iov->iov_len += offset;
  
      last_iov->iov_len += diff;
  
      return ret;
  
  }
  