From 498d86acd9ca0d9d7bc004c1c14c19dc332b77a3 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 12 Nov 2013 11:45:04 +0000 Subject: Fix [5425f2c082]: [fconfigure -error] breaks the background processing of a pending [socket -async]. --- tests/socket.test | 28 ++++++++++++++++++++++++++++ unix/tclUnixSock.c | 19 ++++++++++++++----- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 5542c09..f7e817b 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -1841,6 +1841,7 @@ test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \ after cancel $after close $client close $server + unset x } -result {{} bye} test socket-14.5 {[socket -async] which fails before any connect() can be made} \ -constraints [list socket supported_any] \ @@ -1850,6 +1851,33 @@ test socket-14.5 {[socket -async] which fails before any connect() can be made} } \ -returnCodes 1 \ -result {couldn't open socket: cannot assign requested address} +test socket-14.6 {[socket -async] with no event loop and [fconfigure -error] before the socket is connected} \ + -constraints [list socket supported_any] \ + -setup { + proc accept {s a p} { + puts $s bye + close $s + } + set server [socket -server accept -myaddr 127.0.0.1 0] + set port [lindex [fconfigure $server -sockname] 2] + set x "" + } \ + -body { + set client [socket -async localhost $port] + foreach _ {1 2} { + lappend x [lindex [fconfigure $client -sockname] 0] + lappend x [fconfigure $client -error] + update + } + lappend x [gets $client] + } \ + -cleanup { + close $server + close $client + unset x + } \ + -result [list ::1 "connection refused" 127.0.0.1 "" bye] + ::tcltest::cleanupTests flush stdout return diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index a6360c2..7ef28d8 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -737,7 +737,10 @@ TcpGetOptionProc( if (statePtr->status == 0) { ret = getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, - (char *) &err, &optlen); + (char *) &err, &optlen); + if (statePtr->flags & TCP_ASYNC_CONNECT) { + statePtr->status = err; + } if (ret < 0) { err = errno; } @@ -1054,12 +1057,17 @@ CreateClientSocket( */ optlen = sizeof(int); - getsockopt(state->fds.fd, SOL_SOCKET, SO_ERROR, - (char *) &status, &optlen); - state->status = status; + + if (state->status == 0) { + getsockopt(state->fds.fd, SOL_SOCKET, SO_ERROR, + (char *) &status, &optlen); + state->status = status; + } else { + status = state->status; + state->status = 0; + } } if (status == 0) { - CLEAR_BITS(state->flags, TCP_ASYNC_CONNECT); goto out; } } @@ -1067,6 +1075,7 @@ CreateClientSocket( out: + CLEAR_BITS(state->flags, TCP_ASYNC_CONNECT); if (async_callback) { /* * An asynchonous connection has finally succeeded or failed. -- cgit v0.12 From 68a9570548ce0893129ab3c5a19b38bfd3eb99fb Mon Sep 17 00:00:00 2001 From: max Date: Tue, 12 Nov 2013 13:12:21 +0000 Subject: socket-14.6 only makes sense where both, IPv4 and IPv6 are supported. --- tests/socket.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/socket.test b/tests/socket.test index f7e817b..51219e6 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -1852,7 +1852,7 @@ test socket-14.5 {[socket -async] which fails before any connect() can be made} -returnCodes 1 \ -result {couldn't open socket: cannot assign requested address} test socket-14.6 {[socket -async] with no event loop and [fconfigure -error] before the socket is connected} \ - -constraints [list socket supported_any] \ + -constraints [list socket supported_inet supported_inet6] \ -setup { proc accept {s a p} { puts $s bye -- cgit v0.12 From 729e8b44d736e3ca4af72adb070a8b89cf6fb94e Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 12 Nov 2013 15:43:55 +0000 Subject: [528717] Slight rewording to clarify what the evaluation steps are. --- doc/Tcl.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Tcl.n b/doc/Tcl.n index be0b24d..e868388 100644 --- a/doc/Tcl.n +++ b/doc/Tcl.n @@ -28,7 +28,7 @@ First, the Tcl interpreter breaks the command into \fIwords\fR and performs substitutions as described below. These substitutions are performed in the same way for all commands. -The first word is used to locate a command procedure to +Secondly, first word is used to locate a command procedure to carry out the command, then all of the words of the command are passed to the command procedure. The command procedure is free to interpret each of its words -- cgit v0.12 From dffcad90e2d661e520f735c824ddff5f1d630ddd Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 12 Nov 2013 15:47:21 +0000 Subject: Grammar check... --- doc/Tcl.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Tcl.n b/doc/Tcl.n index e868388..8b17f93 100644 --- a/doc/Tcl.n +++ b/doc/Tcl.n @@ -28,7 +28,7 @@ First, the Tcl interpreter breaks the command into \fIwords\fR and performs substitutions as described below. These substitutions are performed in the same way for all commands. -Secondly, first word is used to locate a command procedure to +Secondly, the first word is used to locate a command procedure to carry out the command, then all of the words of the command are passed to the command procedure. The command procedure is free to interpret each of its words -- cgit v0.12