patch-2.2.4 linux/net/ipv4/tcp.c
Next file: linux/net/ipv4/tcp_input.c
Previous file: linux/net/ipv4/syncookies.c
Back to the patch index
Back to the overall index
- Lines: 125
- Date:
Wed Mar 17 12:39:13 1999
- Orig file:
v2.2.3/linux/net/ipv4/tcp.c
- Orig date:
Wed Mar 10 15:29:52 1999
diff -u --recursive --new-file v2.2.3/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp.c,v 1.136 1999/03/07 13:26:01 davem Exp $
+ * Version: $Id: tcp.c,v 1.139 1999/03/17 19:30:34 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -735,18 +735,25 @@
* Note: must be called with the socket locked.
*/
-int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags)
+int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- int mss_now;
- int err = 0;
- int copied = 0;
+ struct iovec *iov;
+ struct tcp_opt *tp;
struct sk_buff *skb;
+ int iovlen, flags;
+ int mss_now;
+ int err, copied;
+
+ lock_sock(sk);
+
+ err = 0;
+ tp = &(sk->tp_pinfo.af_tcp);
/* Wait for a connection to finish. */
+ flags = msg->msg_flags;
if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
if((err = wait_for_tcp_connect(sk, flags)) != 0)
- return err;
+ goto out;
/* This should be in poll */
sk->socket->flags &= ~SO_NOSPACE; /* clear SIGIO XXX */
@@ -754,6 +761,10 @@
mss_now = tcp_current_mss(sk);
/* Ok commence sending. */
+ iovlen = msg->msg_iovlen;
+ iov = msg->msg_iov;
+ copied = 0;
+
while(--iovlen >= 0) {
int seglen=iov->iov_len;
unsigned char * from=iov->iov_base;
@@ -844,7 +855,7 @@
* for later rather than sent.
*/
copy = tp->snd_wnd - (tp->snd_nxt - tp->snd_una);
- if(copy >= (tp->max_window >> 1))
+ if(copy > (tp->max_window >> 1))
copy = min(copy, mss_now);
else
copy = mss_now;
@@ -926,26 +937,36 @@
}
}
sk->err = 0;
- return copied;
+ err = copied;
+ goto out;
do_sock_err:
if(copied)
- return copied;
- return sock_error(sk);
+ err = copied;
+ else
+ err = sock_error(sk);
+ goto out;
do_shutdown:
if(copied)
- return copied;
- if (!(flags&MSG_NOSIGNAL))
- send_sig(SIGPIPE, current, 0);
- return -EPIPE;
+ err = copied;
+ else {
+ if (!(flags&MSG_NOSIGNAL))
+ send_sig(SIGPIPE, current, 0);
+ err = -EPIPE;
+ }
+ goto out;
do_interrupted:
if(copied)
- return copied;
- return err;
+ err = copied;
+ goto out;
do_fault:
kfree_skb(skb);
do_fault2:
- return -EFAULT;
+ err = -EFAULT;
+out:
+ tcp_push_pending_frames(sk, tp);
+ release_sock(sk);
+ return err;
}
#undef PSH_NEEDED
@@ -1681,13 +1702,9 @@
} else {
sk->nonagle = 0;
- if (tp->send_head) {
- lock_sock(sk);
- if (tp->send_head &&
- tcp_snd_test (sk, tp->send_head))
- tcp_write_xmit(sk);
- release_sock(sk);
- }
+ lock_sock(sk);
+ tcp_push_pending_frames(sk, tp);
+ release_sock(sk);
}
return 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)