sowrite(struct socket *so)

{

	int  n,nn;

	struct sbuf *sb = &so->so_rcv;

	int len = sb->sb_cc;

	struct iovec iov[2];



	DEBUG_CALL("sowrite");

	DEBUG_ARG("so = %p", so);



	if (so->so_urgc) {

		sosendoob(so);

		if (sb->sb_cc == 0)

			return 0;

	}



	/*

	 * No need to check if there's something to write,

	 * sowrite wouldn't have been called otherwise

	 */



	iov[0].iov_base = sb->sb_rptr;

        iov[1].iov_base = NULL;

        iov[1].iov_len = 0;

	if (sb->sb_rptr < sb->sb_wptr) {

		iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;

		/* Should never succeed, but... */

		if (iov[0].iov_len > len) iov[0].iov_len = len;

		n = 1;

	} else {

		iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;

		if (iov[0].iov_len > len) iov[0].iov_len = len;

		len -= iov[0].iov_len;

		if (len) {

			iov[1].iov_base = sb->sb_data;

			iov[1].iov_len = sb->sb_wptr - sb->sb_data;

			if (iov[1].iov_len > len) iov[1].iov_len = len;

			n = 2;

		} else

			n = 1;

	}

	/* Check if there's urgent data to send, and if so, send it */



#ifdef HAVE_READV

	nn = writev(so->s, (const struct iovec *)iov, n);



	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));

#else

	nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);

#endif

	/* This should never happen, but people tell me it does *shrug* */

	if (nn < 0 && (errno == EAGAIN || errno == EINTR))

		return 0;



	if (nn <= 0) {

		DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",

			so->so_state, errno));

		sofcantsendmore(so);

		tcp_sockclosed(sototcpcb(so));

		return -1;

	}



#ifndef HAVE_READV

	if (n == 2 && nn == iov[0].iov_len) {

            int ret;

            ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);

            if (ret > 0)

                nn += ret;

        }

        DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));

#endif



	/* Update sbuf */

	sb->sb_cc -= nn;

	sb->sb_rptr += nn;

	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))

		sb->sb_rptr -= sb->sb_datalen;



	/*

	 * If in DRAIN mode, and there's no more data, set

	 * it CANTSENDMORE

	 */

	if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)

		sofcantsendmore(so);



	return nn;

}

sowrite(struct socket *so)

{

	int  n,nn;

	struct sbuf *sb = &so->so_rcv;

	int len = sb->sb_cc;

	struct iovec iov[2];



	DEBUG_CALL("sowrite");

	DEBUG_ARG("so = %p", so);



	if (so->so_urgc) {

		sosendoob(so);

		if (sb->sb_cc == 0)

			return 0;

	}



	









	iov[0].iov_base = sb->sb_rptr;

        iov[1].iov_base = NULL;

        iov[1].iov_len = 0;

	if (sb->sb_rptr < sb->sb_wptr) {

		iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;

		

		if (iov[0].iov_len > len) iov[0].iov_len = len;

		n = 1;

	} else {

		iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;

		if (iov[0].iov_len > len) iov[0].iov_len = len;

		len -= iov[0].iov_len;

		if (len) {

			iov[1].iov_base = sb->sb_data;

			iov[1].iov_len = sb->sb_wptr - sb->sb_data;

			if (iov[1].iov_len > len) iov[1].iov_len = len;

			n = 2;

		} else

			n = 1;

	}

	



#ifdef HAVE_READV

	nn = writev(so->s, (const struct iovec *)iov, n);



	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));

#else

	nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);

#endif

	

	if (nn < 0 && (errno == EAGAIN || errno == EINTR))

		return 0;



	if (nn <= 0) {

		DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",

			so->so_state, errno));

		sofcantsendmore(so);

		tcp_sockclosed(sototcpcb(so));

		return -1;

	}



#ifndef HAVE_READV

	if (n == 2 && nn == iov[0].iov_len) {

            int ret;

            ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);

            if (ret > 0)

                nn += ret;

        }

        DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));

#endif



	

	sb->sb_cc -= nn;

	sb->sb_rptr += nn;

	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))

		sb->sb_rptr -= sb->sb_datalen;



	







	if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)

		sofcantsendmore(so);



	return nn;

}

		sosendoob(so); 		sosendoob(so); 		DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", 			so->so_state, errno)); 		sofcantsendmore(so); 		tcp_sockclosed(sototcpcb(so)); 		return -1;
FUNC_0(struct socket *VAR_0)

{

	int  VAR_1,VAR_2;

	struct sbuf *VAR_3 = &VAR_0->so_rcv;

	int VAR_4 = VAR_3->sb_cc;

	struct iovec VAR_5[2];



	DEBUG_CALL("FUNC_0");

	DEBUG_ARG("VAR_0 = %p", VAR_0);



	if (VAR_0->so_urgc) {

		sosendoob(VAR_0);

		if (VAR_3->sb_cc == 0)

			return 0;

	}



	









	VAR_5[0].iov_base = VAR_3->sb_rptr;

        VAR_5[1].iov_base = NULL;

        VAR_5[1].iov_len = 0;

	if (VAR_3->sb_rptr < VAR_3->sb_wptr) {

		VAR_5[0].iov_len = VAR_3->sb_wptr - VAR_3->sb_rptr;

		

		if (VAR_5[0].iov_len > VAR_4) VAR_5[0].iov_len = VAR_4;

		VAR_1 = 1;

	} else {

		VAR_5[0].iov_len = (VAR_3->sb_data + VAR_3->sb_datalen) - VAR_3->sb_rptr;

		if (VAR_5[0].iov_len > VAR_4) VAR_5[0].iov_len = VAR_4;

		VAR_4 -= VAR_5[0].iov_len;

		if (VAR_4) {

			VAR_5[1].iov_base = VAR_3->sb_data;

			VAR_5[1].iov_len = VAR_3->sb_wptr - VAR_3->sb_data;

			if (VAR_5[1].iov_len > VAR_4) VAR_5[1].iov_len = VAR_4;

			VAR_1 = 2;

		} else

			VAR_1 = 1;

	}

	



#ifdef HAVE_READV

	VAR_2 = writev(VAR_0->s, (const struct iovec *)VAR_5, VAR_1);



	DEBUG_MISC((dfd, "  ... wrote VAR_2 = %d bytes\VAR_1", VAR_2));

#else

	VAR_2 = slirp_send(VAR_0, VAR_5[0].iov_base, VAR_5[0].iov_len,0);

#endif

	

	if (VAR_2 < 0 && (errno == EAGAIN || errno == EINTR))

		return 0;



	if (VAR_2 <= 0) {

		DEBUG_MISC((dfd, " --- FUNC_0 disconnected, VAR_0->so_state = %x, errno = %d\VAR_1",

			VAR_0->so_state, errno));

		sofcantsendmore(VAR_0);

		tcp_sockclosed(sototcpcb(VAR_0));

		return -1;

	}



#ifndef HAVE_READV

	if (VAR_1 == 2 && VAR_2 == VAR_5[0].iov_len) {

            int VAR_6;

            VAR_6 = slirp_send(VAR_0, VAR_5[1].iov_base, VAR_5[1].iov_len,0);

            if (VAR_6 > 0)

                VAR_2 += VAR_6;

        }

        DEBUG_MISC((dfd, "  ... wrote VAR_2 = %d bytes\VAR_1", VAR_2));

#endif



	

	VAR_3->sb_cc -= VAR_2;

	VAR_3->sb_rptr += VAR_2;

	if (VAR_3->sb_rptr >= (VAR_3->sb_data + VAR_3->sb_datalen))

		VAR_3->sb_rptr -= VAR_3->sb_datalen;



	







	if ((VAR_0->so_state & SS_FWDRAIN) && VAR_3->sb_cc == 0)

		sofcantsendmore(VAR_0);



	return VAR_2;

}

FUNC_0(struct socket *VAR_0)
{ int  VAR_1,VAR_2; struct sbuf *VAR_3 = &VAR_0->so_rcv; int VAR_4 = VAR_3->sb_cc; struct iovec VAR_5[2]; DEBUG_CALL("FUNC_0"); DEBUG_ARG("VAR_0 = %p", VAR_0); if (VAR_0->so_urgc) { sosendoob(VAR_0); if (VAR_3->sb_cc == 0)
return 0; } VAR_5[0].iov_base = VAR_3->sb_rptr; VAR_5[1].iov_base = NULL; VAR_5[1].iov_len = 0; if (VAR_3->sb_rptr < VAR_3->sb_wptr) { VAR_5[0].iov_len = VAR_3->sb_wptr - VAR_3->sb_rptr; if (VAR_5[0].iov_len > VAR_4) VAR_5[0].iov_len = VAR_4; VAR_1 = 1; } else { VAR_5[0].iov_len = (VAR_3->sb_data + VAR_3->sb_datalen) - VAR_3->sb_rptr; if (VAR_5[0].iov_len > VAR_4) VAR_5[0].iov_len = VAR_4; VAR_4 -= VAR_5[0].iov_len; if (VAR_4) { VAR_5[1].iov_base = VAR_3->sb_data; VAR_5[1].iov_len = VAR_3->sb_wptr - VAR_3->sb_data; if (VAR_5[1].iov_len > VAR_4) VAR_5[1].iov_len = VAR_4; VAR_1 = 2; } else VAR_1 = 1; } #ifdef HAVE_READV
VAR_2 = writev(VAR_0->s, (const struct iovec *)VAR_5, VAR_1); DEBUG_MISC((dfd, "  ... wrote VAR_2 = %d bytes\VAR_1", VAR_2)); #else
VAR_2 = slirp_send(VAR_0, VAR_5[0].iov_base, VAR_5[0].iov_len,0); #endif
if (VAR_2 < 0 && (errno == EAGAIN || errno == EINTR))
return 0; if (VAR_2 <= 0) { DEBUG_MISC((dfd, " --- FUNC_0 disconnected, VAR_0->so_state = %x, errno = %d\VAR_1",
VAR_0->so_state, errno)); sofcantsendmore(VAR_0); tcp_sockclosed(sototcpcb(VAR_0)); return -1; } #ifndef HAVE_READV
if (VAR_1 == 2 && VAR_2 == VAR_5[0].iov_len) { int VAR_6; VAR_6 = slirp_send(VAR_0, VAR_5[1].iov_base, VAR_5[1].iov_len,0); if (VAR_6 > 0)
VAR_2 += VAR_6; } DEBUG_MISC((dfd, "  ... wrote VAR_2 = %d bytes\VAR_1", VAR_2)); #endif
VAR_3->sb_cc -= VAR_2; VAR_3->sb_rptr += VAR_2; if (VAR_3->sb_rptr >= (VAR_3->sb_data + VAR_3->sb_datalen))
VAR_3->sb_rptr -= VAR_3->sb_datalen; if ((VAR_0->so_state & SS_FWDRAIN) && VAR_3->sb_cc == 0)
sofcantsendmore(VAR_0); return VAR_2; }