diff options
author | max <max@tclers.tk> | 2012-03-19 16:51:06 (GMT) |
---|---|---|
committer | max <max@tclers.tk> | 2012-03-19 16:51:06 (GMT) |
commit | 922bb1be55898822b118f8354952137ac161b294 (patch) | |
tree | 7c57a6752bb2c00d868118cc445140bc15c1071b | |
parent | 859cb34d2ddbdd2548004b0e044f759ed55e5ebe (diff) | |
download | tcl-922bb1be55898822b118f8354952137ac161b294.zip tcl-922bb1be55898822b118f8354952137ac161b294.tar.gz tcl-922bb1be55898822b118f8354952137ac161b294.tar.bz2 |
* Use the values returned by getaddrinfo() for all three arguments to socket() instead of only using ai_family.
* Try to keep the most meaningful error while iterating over the result list, because using the last error can be misleading.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | unix/tclUnixSock.c | 23 |
2 files changed, 30 insertions, 1 deletions
@@ -1,3 +1,11 @@ +2012-03-19 Reinhard Max <max@suse.de> + + * unix/tclUnixSock.c (Tcl_OpenTcpServer): Use the values returned + by getaddrinfo() for all three arguments to socket() instead of + only using ai_family. Try to keep the most meaningful error while + iterating over the result list, because using the last error can + be misleading. + 2012-03-15 Jan Nijtmans <nijtmans@users.sf.net> * generic/tcl.h: [Bug 3288345] Wrong Tcl_StatBuf used on Cygwin diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 7b5c9e0..8c94e7f 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1252,13 +1252,25 @@ Tcl_OpenTcpServer( const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; + /* + * Try to record and return the most meaningful error message, i.e. the + * one from the first socket that went the farthest before it failed. + */ + enum { START, SOCKET, BIND, LISTEN } howfar = START; + int my_errno = 0; + if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { goto error; } for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { - sock = socket(addrPtr->ai_family, SOCK_STREAM, 0); + sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, + addrPtr->ai_protocol); if (sock == -1) { + if (howfar < SOCKET) { + howfar = SOCKET; + my_errno = errno; + } continue; } @@ -1308,6 +1320,10 @@ Tcl_OpenTcpServer( status = bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen); if (status == -1) { + if (howfar < BIND) { + howfar = BIND; + my_errno = errno; + } close(sock); continue; } @@ -1326,6 +1342,10 @@ Tcl_OpenTcpServer( } status = listen(sock, SOMAXCONN); if (status < 0) { + if (howfar < LISTEN) { + howfar = LISTEN; + my_errno = errno; + } close(sock); continue; } @@ -1367,6 +1387,7 @@ Tcl_OpenTcpServer( return statePtr->channel; } if (interp != NULL) { + errno = my_errno; Tcl_AppendResult(interp, "couldn't open socket: ", Tcl_PosixError(interp), NULL); if (errorMsg != NULL) { |