patch-1.3.67 linux/net/ipv4/tcp.c
Next file: linux/net/ipv4/tcp_input.c
Previous file: linux/net/ipv4/raw.c
Back to the patch index
Back to the overall index
- Lines: 117
- Date:
Tue Feb 20 14:01:03 1996
- Orig file:
v1.3.66/linux/net/ipv4/tcp.c
- Orig date:
Sat Feb 17 16:02:58 1996
diff -u --recursive --new-file v1.3.66/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -422,7 +422,7 @@
unsigned long seq_offset;
struct tcp_mib tcp_statistics;
-static void tcp_close(struct sock *sk, int timeout);
+static void tcp_close(struct sock *sk, unsigned long timeout);
/*
* The less said about this the better, but it works and will do for 1.2 (and 1.4 ;))
@@ -1782,8 +1782,27 @@
release_sock(sk);
}
-static void tcp_close(struct sock *sk, int timeout)
+
+/*
+ * Return 1 if we still have things to send in our buffers.
+ */
+
+static inline int closing(struct sock * sk)
{
+ switch (sk->state) {
+ case TCP_FIN_WAIT1:
+ case TCP_CLOSING:
+ case TCP_LAST_ACK:
+ return 1;
+ }
+ return 0;
+}
+
+
+static void tcp_close(struct sock *sk, unsigned long timeout)
+{
+ struct sk_buff *skb;
+
/*
* We need to grab some memory, and put together a FIN,
* and then put it into the queue to be sent.
@@ -1807,43 +1826,55 @@
if (!sk->dead)
sk->state_change(sk);
- if (timeout == 0)
- {
- struct sk_buff *skb;
-
- /*
- * We need to flush the recv. buffs. We do this only on the
- * descriptor close, not protocol-sourced closes, because the
- * reader process may not have drained the data yet!
- */
+ /*
+ * We need to flush the recv. buffs. We do this only on the
+ * descriptor close, not protocol-sourced closes, because the
+ * reader process may not have drained the data yet!
+ */
- while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
- kfree_skb(skb, FREE_READ);
- /*
- * Get rid off any half-completed packets.
- */
+ while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
+ kfree_skb(skb, FREE_READ);
- if (sk->partial)
- tcp_send_partial(sk);
- }
+ /*
+ * Get rid off any half-completed packets.
+ */
+ if (sk->partial)
+ tcp_send_partial(sk);
/*
* Timeout is not the same thing - however the code likes
* to send both the same way (sigh).
*/
- if(timeout)
+ if (tcp_close_state(sk,1)==1)
{
- tcp_set_state(sk, TCP_CLOSE); /* Dead */
+ tcp_send_fin(sk);
}
- else
- {
- if(tcp_close_state(sk,1)==1)
+
+ if (timeout) {
+ cli();
+ release_sock(sk);
+ current->timeout = timeout;
+ while(closing(sk) && current->timeout)
{
- tcp_send_fin(sk);
+ interruptible_sleep_on(sk->sleep);
+ if (current->signal & ~current->blocked)
+ {
+ break;
+ }
}
+ current->timeout=0;
+ lock_sock(sk);
+ sti();
}
+
+ /*
+ * This will destroy it. The timers will take care of actually
+ * free'ing up the memory.
+ */
+ sk->dead = 1;
+ tcp_cache_zap(); /* Kill the cache again. */
release_sock(sk);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this