diff options
| author | max <max@tclers.tk> | 2011-06-07 14:31:59 (GMT) | 
|---|---|---|
| committer | max <max@tclers.tk> | 2011-06-07 14:31:59 (GMT) | 
| commit | 938cb914fee8405b397ae0823e16444bc9eb7c0c (patch) | |
| tree | a368a1979b1ea5a20da1082b04a726a11f927b33 /unix/tclUnixSock.c | |
| parent | cd37602cf4924672b4219fdf144d76e2cf773947 (diff) | |
| download | tcl-938cb914fee8405b397ae0823e16444bc9eb7c0c.zip tcl-938cb914fee8405b397ae0823e16444bc9eb7c0c.tar.gz tcl-938cb914fee8405b397ae0823e16444bc9eb7c0c.tar.bz2 | |
Fix bug#3084338, a memleak when a [socket -async] was closed before the connection had succeeded or failed.
Diffstat (limited to 'unix/tclUnixSock.c')
| -rw-r--r-- | unix/tclUnixSock.c | 51 | 
1 files 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;      } | 
