From 938cb914fee8405b397ae0823e16444bc9eb7c0c Mon Sep 17 00:00:00 2001 From: max Date: Tue, 7 Jun 2011 14:31:59 +0000 Subject: Fix bug#3084338, a memleak when a [socket -async] was closed before the connection had succeeded or failed. --- unix/tclUnixSock.c | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 0d6b1d0..39fb375 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -53,27 +53,21 @@ struct TcpState { TcpFdList *fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ - union { - struct { - /* Only needed for server sockets */ - Tcl_TcpAcceptProc *acceptProc; - /* Proc to call on accept. */ - ClientData acceptProcData; - /* The data for the accept proc. */ - }; - struct { - /* - * Only needed for client sockets - */ - struct addrinfo *addrlist; /* addresses to connect to */ - struct addrinfo *addr; /* iterator over addrlist */ - struct addrinfo *myaddrlist; /* local address */ - struct addrinfo *myaddr; /* iterator over myaddrlist */ - int filehandlers; /* Caches FileHandlers that get set up while - * an async socket is not yet connected */ - int status; /* Cache status of async socket */ - }; - }; + /* + * Only needed for server sockets + */ + Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */ + ClientData acceptProcData; /* The data for the accept proc. */ + /* + * Only needed for client sockets + */ + struct addrinfo *addrlist; /* addresses to connect to */ + struct addrinfo *addr; /* iterator over addrlist */ + struct addrinfo *myaddrlist; /* local address */ + struct addrinfo *myaddr; /* iterator over myaddrlist */ + int filehandlers; /* Caches FileHandlers that get set up while + * an async socket is not yet connected */ + int status; /* Cache status of async socket */ }; /* @@ -551,6 +545,12 @@ TcpCloseProc( } ckfree(fds); } + if (statePtr->addrlist != NULL) { + freeaddrinfo(statePtr->addrlist); + } + if (statePtr->myaddrlist != NULL) { + freeaddrinfo(statePtr->myaddrlist); + } ckfree(statePtr); return errorCode; } @@ -993,9 +993,6 @@ CreateClientSocket( out: - freeaddrinfo(state->addrlist); - freeaddrinfo(state->myaddrlist); - if (async) { CLEAR_BITS(state->flags, TCP_ASYNC_CONNECT); TcpWatchProc(state, state->filehandlers); @@ -1010,11 +1007,6 @@ out: Tcl_AppendResult(interp, "couldn't open socket: ", Tcl_PosixError(interp), NULL); } - if (state->fds->fd != -1) { - close(state->fds->fd); - } - ckfree(state->fds); - ckfree(state); return TCL_ERROR; } } @@ -1088,6 +1080,7 @@ Tcl_OpenTcpClient( * Create a new client socket and wrap it in a channel. */ if (CreateClientSocket(interp, state) != TCL_OK) { + TcpCloseProc(state, NULL); return NULL; } -- cgit v0.12