aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanyil Bohdan <danyil.bohdan@gmail.com>2014-07-26 10:50:17 +0300
committerSteve Bennett <steveb@workware.net.au>2014-09-01 08:07:05 +1000
commita71a09f67ceb1bdadde86981da76d4f42dffab81 (patch)
treef97b52d991df6de7d2770964cd3ab67be341d52b
parent0c24afc040fcdcdc51513ea946a1cf4b36987a09 (diff)
downloadjimtcl-a71a09f67ceb1bdadde86981da76d4f42dffab81.zip
jimtcl-a71a09f67ceb1bdadde86981da76d4f42dffab81.tar.gz
jimtcl-a71a09f67ceb1bdadde86981da76d4f42dffab81.tar.bz2
aio: optional argument addrvar for accept.
-rw-r--r--examples/tcp.server3
-rw-r--r--jim-aio.c28
-rw-r--r--jim_tcl.txt8
-rw-r--r--tests/event.test35
4 files changed, 67 insertions, 7 deletions
diff --git a/examples/tcp.server b/examples/tcp.server
index 1240f2b..a86cd63 100644
--- a/examples/tcp.server
+++ b/examples/tcp.server
@@ -6,7 +6,8 @@ set s [socket stream.server 20000]
$s readable {
# Clean up children
os.wait -nohang 0
- set sock [$s accept]
+ set sock [$s accept addr]
+ puts "Client address: $addr"
# Make this server forking so we can accept multiple
# simultaneous connections
diff --git a/jim-aio.c b/jim-aio.c
index 70fc1e3..37e1ea7 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -623,6 +623,30 @@ static int aio_cmd_accept(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_ERR;
}
+ if (argc > 0) {
+ /* INET6_ADDRSTRLEN is 46. Add some for [] and port */
+ char addrbuf[60];
+
+#if IPV6
+ if (sa.sa.sa_family == PF_INET6) {
+ addrbuf[0] = '[';
+ /* Allow 9 for []:65535\0 */
+ inet_ntop(sa.sa.sa_family, &sa.sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9);
+ snprintf(addrbuf + strlen(addrbuf), 8, "]:%d", ntohs(sa.sin.sin_port));
+ }
+ else
+#endif
+ if (sa.sa.sa_family == PF_INET) {
+ /* Allow 7 for :65535\0 */
+ inet_ntop(sa.sa.sa_family, &sa.sin.sin_addr, addrbuf, sizeof(addrbuf) - 7);
+ snprintf(addrbuf + strlen(addrbuf), 7, ":%d", ntohs(sa.sin.sin_port));
+ }
+
+ if (Jim_SetVariable(interp, argv[0], Jim_NewStringObj(interp, addrbuf, -1)) != JIM_OK) {
+ return JIM_ERR;
+ }
+ }
+
/* Create the file command */
return JimMakeChannel(interp, NULL, sock, Jim_NewStringObj(interp, "accept", -1),
"aio.sockstream%ld", af->addr_family, "r+");
@@ -916,10 +940,10 @@ static const jim_subcmd_type aio_command_table[] = {
/* Description: Send 'str' to the given address (dgram only) */
},
{ "accept",
- NULL,
+ "?addrvar?",
aio_cmd_accept,
0,
- 0,
+ 1,
/* Description: Server socket only: Accept a connection and return stream */
},
{ "listen",
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 255d12b..d6172b9 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -4431,14 +4431,16 @@ See `open` and `socket` for commands which return an I/O handle.
aio
~~~
-+$handle *accept*+::
- Server socket only: Accept a connection and return stream
++$handle *accept* ?addrvar?+::
+ Server socket only: Accept a connection and return stream.
+ If +'addrvar'+ is specified, the address of the connected client is stored
+ in the named variable in the form 'addr:port'. See `socket` for details.
+$handle *buffering none|line|full*+::
Sets the buffering mode of the stream.
+$handle *close* ?r(ead)|w(rite)?+::
- Closes the stream.
+ Closes the stream.
The two-argument form is a "half-close" on a socket. See the +shutdown(2)+ man page.
+$handle *copyto* 'tofd ?size?'+::
diff --git a/tests/event.test b/tests/event.test
index 856e0cc..096f21b 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -15,6 +15,8 @@ needs cmd after eventloop
testConstraint socket [expr {[info commands socket] ne ""}]
testConstraint exec [expr {[info commands exec] ne ""}]
testConstraint signal [expr {[info commands signal] ne ""}]
+catch {[socket -ipv6 stream ::1:5000]} ipv6res
+testConstraint ipv6 [expr {$ipv6res ne "ipv6 not supported"}]
test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} jim {
catch {rename bgerror {}}
@@ -152,7 +154,6 @@ test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} {s
list $x $y $z
} {3 3 done}
-
test event-12.1 {Tcl_UpdateCmd procedure} {
list [catch {update a b} msg] $msg
} {1 {wrong # args: should be "update ?idletasks?"}}
@@ -200,4 +201,36 @@ test event-13.1 "vwait/signal" signal {
} msg] $msg
} {5 SIGALRM}
+
+test event-14.1 {socket stream.server client address} {jim socket} {
+ set s1 [socket stream.server 5001]
+ after 200
+ set s2 [socket stream 127.0.0.1:5001]
+ set addr {}
+ $s1 readable {
+ $s1 accept addr
+ }
+ vwait addr
+ $s1 close
+ $s2 close
+ # Return client address without the port.
+ list [lindex [split $addr :] 0]
+} {127.0.0.1}
+
+test event-14.2 {IPv6 socket stream.server client address} {jim socket ipv6} {
+ set s1 [socket -ipv6 stream.server ::1:5001]
+ after 200
+ set s2 [socket -ipv6 stream ::1:5001]
+ set addr6 {}
+ $s1 readable {
+ $s1 accept addr6
+ }
+ vwait addr6
+ $s1 close
+ $s2 close
+ # Return client IPv6 address without the port.
+ list [join [lrange [split $addr6 :] 0 end-1] :]
+} {{[::1]}}
+
+
testreport