diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-15 18:58:22 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-15 18:58:22 +0000 |
commit | f2675bf333e0378c842717a94a13c73dabb76a52 (patch) | |
tree | 6a460f3749d40743ca8d1d1dfb95481342860110 /nuttx/net/net_close.c | |
parent | 6ee68a773a24586f6e6cfaccdf7dce064d213e88 (diff) | |
download | px4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.tar.gz px4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.tar.bz2 px4-nuttx-f2675bf333e0378c842717a94a13c73dabb76a52.zip |
dup() and dup2() support for socket descriptors
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1884 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net/net_close.c')
-rw-r--r-- | nuttx/net/net_close.c | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c index 7ce1f9fa4..f8de0614a 100644 --- a/nuttx/net/net_close.c +++ b/nuttx/net/net_close.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/net_close.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ struct tcp_close_s { FAR struct socket *cl_psock; /* Reference to the TCP socket */ FAR struct uip_callback_s *cl_cb; /* Reference to TCP callback instance */ - sem_t cl_sem; /* Semaphore signals disconnect completion */ + sem_t cl_sem; /* Semaphore signals disconnect completion */ }; #endif @@ -222,33 +222,75 @@ int net_close(int sockfd) goto errout; } - /* Perform uIP side of the close depending on the protocol type */ + /* We perform the uIP close operation only if this is the last count on the socket. + * (actually, I think the socket crefs only takes the values 0 and 1 right now). + */ - switch (psock->s_type) + if (psock->s_crefs <= 1) { -#ifdef CONFIG_NET_TCP - case SOCK_STREAM: + /* Perform uIP side of the close depending on the protocol type */ + + switch (psock->s_type) { - struct uip_conn *conn = psock->s_conn; - uip_unlisten(conn); /* No longer accepting connections */ - netclose_disconnect(psock); /* Break any current connections */ - uip_tcpfree(conn); /* Free uIP resources */ - } - break; +#ifdef CONFIG_NET_TCP + case SOCK_STREAM: + { + struct uip_conn *conn = psock->s_conn; + + /* Is this the last reference to the connection structure (there + * could be more if the socket was dup'ed. + */ + + if (conn->crefs <= 1) + { + /* Yes... free the connection structure */ + + uip_unlisten(conn); /* No longer accepting connections */ + netclose_disconnect(psock); /* Break any current connections */ + uip_tcpfree(conn); /* Free uIP resources */ + } + else + { + /* No.. Just decrement the reference count */ + + conn->crefs--; + } + } + break; #endif #ifdef CONFIG_NET_UDP - case SOCK_DGRAM: - uip_udpfree(psock->s_conn); /* Free uIP resources */ - break; + case SOCK_DGRAM: + { + struct uip_udp_conn *conn = psock->s_conn; + + /* Is this the last reference to the connection structure (there + * could be more if the socket was dup'ed. + */ + + if (conn->crefs <= 1) + { + /* Yes... free the connection structure */ + + uip_udpfree(psock->s_conn); /* Free uIP resources */ + } + else + { + /* No.. Just decrement the reference count */ + + conn->crefs--; + } + } + break; #endif - default: - err = EBADF; - goto errout; + default: + err = EBADF; + goto errout; + } } - /* Then release the socket structure containing the connection */ + /* Then release our reference on the socket structure containing the connection */ sockfd_release(sockfd); return OK; |