From a7f1ab1afd109c2c02de573a66aaab15bfbdeab1 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 6 Jun 2011 15:07:23 +0000 Subject: * Don't use port 0 for test 14.2 as it fails in different ways on Linux and NetBSD. * Unify channel name creation. * Prevent error messages from appearing twice. * Double the measured latency in socket.test to be on the safe side. --- tests/socket.test | 4 ++-- unix/tclUnixSock.c | 59 +++++++++++++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index b121022..39dc8de 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -85,7 +85,7 @@ puts $s2 test1; gets $s1 puts $s2 test2; gets $s1 close $s1; close $s2 set t2 [clock milliseconds] -set latency [expr {$t2-$t1}] +set latency [expr {($t2-$t1)*2}]; # doubled as a safety margin unset t1 t2 s1 s2 server # If remoteServerIP or remoteServerPort are not set, check in the environment @@ -1768,7 +1768,7 @@ test socket-14.1 {[socket -async] fileevent while still connecting} \ test socket-14.2 {[socket -async] fileevent connection refused} \ -constraints [list socket supported_any] \ -body { - set client [socket -async localhost 0] + set client [socket -async localhost [randport]] fileevent $client writable {set x [fconfigure $client -error]} set after [after 1000 {set x timeout}] vwait x diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 981162d..0d6b1d0 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -20,6 +20,10 @@ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) +/* "sock" + a pointer in hex + \0 */ +#define SOCK_CHAN_LENGTH 4 + sizeof(void*) * 2 + 1 +#define SOCK_TEMPLATE "sock%lx" + /* * This is needed to comply with the strict aliasing rules of GCC, but it also * simplifies casting between the different sockaddr types. @@ -887,7 +891,7 @@ CreateClientSocket( { socklen_t optlen; int in_coro = (state->addr != NULL); - int status, connected = 0; + int status; int async = state->flags & TCP_ASYNC_CONNECT; if (in_coro) { @@ -1000,7 +1004,7 @@ out: if (status < 0) { if (in_coro) { - Tcl_NotifyChannel(state->fds->fd, TCL_WRITABLE); + Tcl_NotifyChannel(state->channel, TCL_WRITABLE); } else { if (interp != NULL) { Tcl_AppendResult(interp, "couldn't open socket: ", @@ -1047,20 +1051,25 @@ Tcl_OpenTcpClient( { TcpState *state; const char *errorMsg = NULL; - struct addrinfo *addrlist, *myaddrlist; - char channelName[4+16+1]; /* "sock" + up to 16 hex chars + \0 */ - + struct addrinfo *addrlist = NULL, *myaddrlist = NULL; + char channelName[SOCK_CHAN_LENGTH]; /* * Do the name lookups for the local and remote addresses. */ - if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg)) { - goto error; - } - if (!TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, - &errorMsg)) { - freeaddrinfo(addrlist); - goto error; + if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg) || + !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, &errorMsg)) { + if (addrlist != NULL) { + freeaddrinfo(addrlist); + } + if (interp != NULL) { + Tcl_AppendResult(interp, "couldn't open socket: ", + Tcl_PosixError(interp), NULL); + if (errorMsg != NULL) { + Tcl_AppendResult(interp, " (", errorMsg, ")", NULL); + } + } + return NULL; } /* @@ -1079,10 +1088,10 @@ Tcl_OpenTcpClient( * Create a new client socket and wrap it in a channel. */ if (CreateClientSocket(interp, state) != TCL_OK) { - goto error; + return NULL; } - sprintf(channelName, "sock%lx", (long)state); + sprintf(channelName, SOCK_TEMPLATE, (long)state); state->channel = Tcl_CreateChannel(&tcpChannelType, channelName, state, (TCL_READABLE | TCL_WRITABLE)); @@ -1092,16 +1101,6 @@ Tcl_OpenTcpClient( return NULL; } return state->channel; - -error: - if (interp != NULL) { - Tcl_AppendResult(interp, "couldn't open socket: ", - Tcl_PosixError(interp), NULL); - if (errorMsg != NULL) { - Tcl_AppendResult(interp, " (", errorMsg, ")", NULL); - } - } - return NULL; } /* @@ -1151,7 +1150,7 @@ TclpMakeTcpClientChannelMode( * TCL_WRITABLE to indicate file mode. */ { TcpState *statePtr; - char channelName[16 + TCL_INTEGER_SPACE]; + char channelName[SOCK_CHAN_LENGTH]; statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); @@ -1160,7 +1159,7 @@ TclpMakeTcpClientChannelMode( statePtr->fds->fd = PTR2INT(sock); statePtr->flags = 0; - sprintf(channelName, "sock%d", statePtr->fds->fd); + sprintf(channelName, SOCK_TEMPLATE, (long)statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, mode); @@ -1202,7 +1201,7 @@ Tcl_OpenTcpServer( int status = 0, sock = -1, reuseaddr = 1, chosenport = 0; struct addrinfo *addrlist = NULL, *addrPtr; /* socket address */ TcpState *statePtr = NULL; - char channelName[16 + TCL_INTEGER_SPACE]; + char channelName[SOCK_CHAN_LENGTH]; const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; @@ -1295,7 +1294,7 @@ Tcl_OpenTcpServer( statePtr->fds = newfds; statePtr->acceptProc = acceptProc; statePtr->acceptProcData = acceptProcData; - sprintf(channelName, "sock%d", sock); + sprintf(channelName, SOCK_TEMPLATE, (long)statePtr); } else { fds->next = newfds; } @@ -1360,7 +1359,7 @@ TcpAccept( TcpState *newSockState; /* State for new socket. */ address addr; /* The remote address */ socklen_t len; /* For accept interface */ - char channelName[16 + TCL_INTEGER_SPACE]; + char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; len = sizeof(addr); @@ -1383,7 +1382,7 @@ TcpAccept( memset(newSockState->fds, (int) 0, sizeof(TcpFdList)); newSockState->fds->fd = newsock; - sprintf(channelName, "sock%d", newsock); + sprintf(channelName, SOCK_TEMPLATE, (long)newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newSockState, (TCL_READABLE | TCL_WRITABLE)); -- cgit v0.12