summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormax <max@tclers.tk>2012-03-19 16:51:06 (GMT)
committermax <max@tclers.tk>2012-03-19 16:51:06 (GMT)
commit922bb1be55898822b118f8354952137ac161b294 (patch)
tree7c57a6752bb2c00d868118cc445140bc15c1071b
parent859cb34d2ddbdd2548004b0e044f759ed55e5ebe (diff)
downloadtcl-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--ChangeLog8
-rw-r--r--unix/tclUnixSock.c23
2 files changed, 30 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a8e4bb8..4f894be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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) {