socket.test
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:44k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # Commands tested in this file: socket.
  2. #
  3. # This file contains a collection of tests for one or more of the Tcl
  4. # built-in commands.  Sourcing this file into Tcl runs the tests and
  5. # generates output for errors.  No output means no errors were found.
  6. #
  7. # Copyright (c) 1994-1996 Sun Microsystems, Inc.
  8. # Copyright (c) 1998-2000 Ajuba Solutions.
  9. #
  10. # See the file "license.terms" for information on usage and redistribution
  11. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12. #
  13. # RCS: @(#) $Id: socket.test,v 1.26.2.6 2006/03/16 00:35:59 andreas_kupries Exp $
  14. # Running socket tests with a remote server:
  15. # ------------------------------------------
  16. # Some tests in socket.test depend on the existence of a remote server to
  17. # which they connect. The remote server must be an instance of tcltest and it
  18. # must run the script found in the file "remote.tcl" in this directory. You
  19. # can start the remote server on any machine reachable from the machine on
  20. # which you want to run the socket tests, by issuing:
  21. #     tcltest remote.tcl -port 2048 # Or choose another port number.
  22. # If the machine you are running the remote server on has several IP
  23. # interfaces, you can choose which interface the server listens on for
  24. # connections by specifying the -address command line flag, so:
  25. #     tcltest remote.tcl -address your.machine.com
  26. # These options can also be set by environment variables. On Unix, you can
  27. # type these commands to the shell from which the remote server is started:
  28. #     shell% setenv serverPort 2048
  29. #     shell% setenv serverAddress your.machine.com
  30. # and subsequently you can start the remote server with:
  31. #     tcltest remote.tcl
  32. # to have it listen on port 2048 on the interface your.machine.com.
  33. #     
  34. # When the server starts, it prints out a detailed message containing its
  35. # configuration information, and it will block until killed with a Ctrl-C.
  36. # Once the remote server exists, you can run the tests in socket.test with
  37. # the server by setting two Tcl variables:
  38. #     % set remoteServerIP <name or address of machine on which server runs>
  39. #     % set remoteServerPort 2048
  40. # These variables are also settable from the environment. On Unix, you can:
  41. #     shell% setenv remoteServerIP machine.where.server.runs
  42. #     shell% senetv remoteServerPort 2048
  43. # The preamble of the socket.test file checks to see if the variables are set
  44. # either in Tcl or in the environment; if they are, it attempts to connect to
  45. # the server. If the connection is successful, the tests using the remote
  46. # server will be performed; otherwise, it will attempt to start the remote
  47. # server (via exec) on platforms that support this, on the local host,
  48. # listening at port 2048. If all fails, a message is printed and the tests
  49. # using the remote server are not performed.
  50. package require tcltest 2
  51. namespace import -force ::tcltest::*
  52. # Some tests require the testthread and exec commands
  53. testConstraint testthread [llength [info commands testthread]]
  54. testConstraint exec [llength [info commands exec]]
  55. # If remoteServerIP or remoteServerPort are not set, check in the
  56. # environment variables for externally set values.
  57. #
  58. if {![info exists remoteServerIP]} {
  59.     if {[info exists env(remoteServerIP)]} {
  60. set remoteServerIP $env(remoteServerIP)
  61.     }
  62. }
  63. if {![info exists remoteServerPort]} {
  64.     if {[info exists env(remoteServerIP)]} {
  65. set remoteServerPort $env(remoteServerPort)
  66.     } else {
  67.         if {[info exists remoteServerIP]} {
  68.     set remoteServerPort 2048
  69.         }
  70.     }
  71. }
  72. #
  73. # Check if we're supposed to do tests against the remote server
  74. #
  75. set doTestsWithRemoteServer 1
  76. if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
  77.     set remoteServerIP 127.0.0.1
  78. }
  79. if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
  80.     set remoteServerPort 2048
  81. }
  82. # Attempt to connect to a remote server if one is already running. If it
  83. # is not running or for some other reason the connect fails, attempt to
  84. # start the remote server on the local host listening on port 2048. This
  85. # is only done on platforms that support exec (i.e. not on the Mac). On
  86. # platforms that do not support exec, the remote server must be started
  87. # by the user before running the tests.
  88. set remoteProcChan ""
  89. set commandSocket ""
  90. if {$doTestsWithRemoteServer} {
  91.     catch {close $commandSocket}
  92.     if {[catch {set commandSocket [socket $remoteServerIP 
  93. $remoteServerPort]}] != 0} {
  94. if {[info commands exec] == ""} {
  95.     set noRemoteTestReason "can't exec"
  96.     set doTestsWithRemoteServer 0
  97. } else {
  98.     set remoteServerIP 127.0.0.1
  99.     # Be *extra* careful in case this file is sourced from
  100.     # a directory other than the current one...
  101.     set remoteFile [file join [pwd] [file dirname [info script]] 
  102.     remote.tcl]
  103.     if {[catch {set remoteProcChan 
  104. [open "|[list [interpreter] $remoteFile 
  105. -serverIsSilent 
  106. -port $remoteServerPort 
  107. -address $remoteServerIP]" 
  108. w+]} 
  109.    msg] == 0} {
  110. after 1000
  111. if {[catch {set commandSocket [socket $remoteServerIP 
  112. $remoteServerPort]} msg] == 0} {
  113.     fconfigure $commandSocket -translation crlf -buffering line
  114. } else {
  115.     set noRemoteTestReason $msg
  116.     set doTestsWithRemoteServer 0
  117. }
  118.     } else {
  119. set noRemoteTestReason "$msg [interpreter]"
  120. set doTestsWithRemoteServer 0
  121.     }
  122. }
  123.     } else {
  124. fconfigure $commandSocket -translation crlf -buffering line
  125.     }
  126. }
  127. # Some tests are run only if we are doing testing against a remote server.
  128. set ::tcltest::testConstraints(doTestsWithRemoteServer) $doTestsWithRemoteServer
  129. if {$doTestsWithRemoteServer == 0} {
  130.     if {[string first s $::tcltest::verbose] != -1} {
  131.      puts "Skipping tests with remote server. See tests/socket.test for"
  132. puts "information on how to run remote server."
  133. puts "Reason for not doing remote tests: $noRemoteTestReason"
  134.     }
  135. }
  136. #
  137. # If we do the tests, define a command to send a command to the
  138. # remote server.
  139. #
  140. if {$doTestsWithRemoteServer == 1} {
  141.     proc sendCommand {c} {
  142. global commandSocket
  143. if {[eof $commandSocket]} {
  144.     error "remote server disappeared"
  145. }
  146. if {[catch {puts $commandSocket $c} msg]} {
  147.     error "remote server disappaered: $msg"
  148. }
  149. if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
  150.     error "remote server disappeared: $msg"
  151. }
  152. set resp ""
  153. while {1} {
  154.     set line [gets $commandSocket]
  155.     if {[eof $commandSocket]} {
  156. error "remote server disappaered"
  157.     }
  158.     if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
  159. if {[string compare [lindex $resp 0] error] == 0} {
  160.     error [lindex $resp 1]
  161. } else {
  162.     return [lindex $resp 1]
  163. }
  164.     } else {
  165. append resp $line "n"
  166.     }
  167. }
  168.     }
  169. }
  170. test socket-1.1 {arg parsing for socket command} {socket} {
  171.     list [catch {socket -server} msg] $msg
  172. } {1 {no argument given for -server option}}
  173. test socket-1.2 {arg parsing for socket command} {socket} {
  174.     list [catch {socket -server foo} msg] $msg
  175. } {1 {wrong # args: should be either:
  176. socket ?-myaddr addr? ?-myport myport? ?-async? host port
  177. socket -server command ?-myaddr addr? port}}
  178. test socket-1.3 {arg parsing for socket command} {socket} {
  179.     list [catch {socket -myaddr} msg] $msg
  180. } {1 {no argument given for -myaddr option}}
  181. test socket-1.4 {arg parsing for socket command} {socket} {
  182.     list [catch {socket -myaddr 127.0.0.1} msg] $msg
  183. } {1 {wrong # args: should be either:
  184. socket ?-myaddr addr? ?-myport myport? ?-async? host port
  185. socket -server command ?-myaddr addr? port}}
  186. test socket-1.5 {arg parsing for socket command} {socket} {
  187.     list [catch {socket -myport} msg] $msg
  188. } {1 {no argument given for -myport option}}
  189. test socket-1.6 {arg parsing for socket command} {socket} {
  190.     list [catch {socket -myport xxxx} msg] $msg
  191. } {1 {expected integer but got "xxxx"}}
  192. test socket-1.7 {arg parsing for socket command} {socket} {
  193.     list [catch {socket -myport 2522} msg] $msg
  194. } {1 {wrong # args: should be either:
  195. socket ?-myaddr addr? ?-myport myport? ?-async? host port
  196. socket -server command ?-myaddr addr? port}}
  197. test socket-1.8 {arg parsing for socket command} {socket} {
  198.     list [catch {socket -froboz} msg] $msg
  199. } {1 {bad option "-froboz": must be -async, -myaddr, -myport, or -server}}
  200. test socket-1.9 {arg parsing for socket command} {socket} {
  201.     list [catch {socket -server foo -myport 2521 3333} msg] $msg
  202. } {1 {Option -myport is not valid for servers}}
  203. test socket-1.10 {arg parsing for socket command} {socket} {
  204.     list [catch {socket host 2528 -junk} msg] $msg
  205. } {1 {wrong # args: should be either:
  206. socket ?-myaddr addr? ?-myport myport? ?-async? host port
  207. socket -server command ?-myaddr addr? port}}
  208. test socket-1.11 {arg parsing for socket command} {socket} {
  209.     list [catch {socket -server callback 2520 --} msg] $msg
  210. } {1 {wrong # args: should be either:
  211. socket ?-myaddr addr? ?-myport myport? ?-async? host port
  212. socket -server command ?-myaddr addr? port}}
  213. test socket-1.12 {arg parsing for socket command} {socket} {
  214.     list [catch {socket foo badport} msg] $msg
  215. } {1 {expected integer but got "badport"}}
  216. test socket-1.13 {arg parsing for socket command} {socket} {
  217. list [catch {socket -async -server} msg] $msg
  218. } {1 {cannot set -async option for server sockets}}
  219. test socket-1.14 {arg parsing for socket command} {socket} {
  220. list [catch {socket -server foo -async} msg] $msg
  221. } {1 {cannot set -async option for server sockets}}
  222. set path(script) [makeFile {} script]
  223. test socket-2.1 {tcp connection} {socket stdio} {
  224.     file delete $path(script)
  225.     set f [open $path(script) w]
  226.     puts $f {
  227. set timer [after 10000 "set x timed_out"]
  228. set f [socket -server accept 0]
  229. proc accept {file addr port} {
  230.     global x
  231.     set x done
  232.             close $file
  233. }
  234. puts ready
  235. puts [lindex [fconfigure $f -sockname] 2]
  236. vwait x
  237. after cancel $timer
  238. close $f
  239. puts $x
  240.     }
  241.     close $f
  242.     set f [open "|[list [interpreter] $path(script)]" r]
  243.     gets $f x
  244.     gets $f listen
  245.     if {[catch {socket 127.0.0.1 $listen} msg]} {
  246.         set x $msg
  247.     } else {
  248.         lappend x [gets $f]
  249.         close $msg
  250.     }
  251.     lappend x [gets $f]
  252.     close $f
  253.     set x
  254. } {ready done {}}
  255. if [info exists port] {
  256.     incr port
  257. } else { 
  258.     set port [expr 2048 + [pid]%1024]
  259. }
  260. test socket-2.2 {tcp connection with client port specified} {socket stdio} {
  261.     file delete $path(script)
  262.     set f [open $path(script) w]
  263.     puts $f {
  264. set timer [after 10000 "set x timeout"]
  265.         set f [socket -server accept 0]
  266. proc accept {file addr port} {
  267.             global x
  268.             puts "[gets $file] $port"
  269.             close $file
  270.             set x done
  271. }
  272. puts ready
  273. puts [lindex [fconfigure $f -sockname] 2]
  274. vwait x
  275. after cancel $timer
  276. close $f
  277.     }
  278.     close $f
  279.     set f [open "|[list [interpreter] $path(script)]" r]
  280.     gets $f x
  281.     gets $f listen
  282.     global port
  283.     if {[catch {socket -myport $port 127.0.0.1 $listen} sock]} {
  284.         set x $sock
  285. close [socket 127.0.0.1 $listen]
  286. puts stderr $sock
  287.     } else {
  288.         puts $sock hello
  289. flush $sock
  290.         lappend x [gets $f]
  291.         close $sock
  292.     }
  293.     close $f
  294.     set x
  295. } [list ready "hello $port"]
  296. test socket-2.3 {tcp connection with client interface specified} {socket stdio} {
  297.     file delete $path(script)
  298.     set f [open $path(script) w]
  299.     puts $f {
  300. set timer [after 2000 "set x done"]
  301.         set f [socket  -server accept 2830]
  302. proc accept {file addr port} {
  303.             global x
  304.             puts "[gets $file] $addr"
  305.             close $file
  306.             set x done
  307. }
  308. puts ready
  309. vwait x
  310. after cancel $timer
  311. close $f
  312.     }
  313.     close $f
  314.     set f [open "|[list [interpreter] $path(script)]" r]
  315.     gets $f x
  316.     if {[catch {socket -myaddr 127.0.0.1 127.0.0.1 2830} sock]} {
  317.         set x $sock
  318.     } else {
  319.         puts $sock hello
  320. flush $sock
  321.         lappend x [gets $f]
  322.         close $sock
  323.     }
  324.     close $f
  325.     set x
  326. } {ready {hello 127.0.0.1}}
  327. test socket-2.4 {tcp connection with server interface specified} {socket stdio} {
  328.     file delete $path(script)
  329.     set f [open $path(script) w]
  330.     puts $f {
  331. set timer [after 2000 "set x done"]
  332.         set f [socket -server accept -myaddr 127.0.0.1 0]
  333. proc accept {file addr port} {
  334.             global x
  335.             puts "[gets $file]"
  336.             close $file
  337.             set x done
  338. }
  339. puts ready
  340. puts [lindex [fconfigure $f -sockname] 2]
  341. vwait x
  342. after cancel $timer
  343. close $f
  344.     }
  345.     close $f
  346.     set f [open "|[list [interpreter] $path(script)]" r]
  347.     gets $f x
  348.     gets $f listen
  349.     if {[catch {socket 127.0.0.1 $listen} sock]} {
  350.         set x $sock
  351.     } else {
  352.         puts $sock hello
  353. flush $sock
  354.         lappend x [gets $f]
  355.         close $sock
  356.     }
  357.     close $f
  358.     set x
  359. } {ready hello}
  360. test socket-2.5 {tcp connection with redundant server port} {socket stdio} {
  361.     file delete $path(script)
  362.     set f [open $path(script) w]
  363.     puts $f {
  364. set timer [after 10000 "set x timeout"]
  365.         set f [socket -server accept 0]
  366. proc accept {file addr port} {
  367.             global x
  368.             puts "[gets $file]"
  369.             close $file
  370.             set x done
  371. }
  372. puts ready
  373. puts [lindex [fconfigure $f -sockname] 2]
  374. vwait x
  375. after cancel $timer
  376. close $f
  377.     }
  378.     close $f
  379.     set f [open "|[list [interpreter] $path(script)]" r]
  380.     gets $f x
  381.     gets $f listen
  382.     if {[catch {socket 127.0.0.1 $listen} sock]} {
  383.         set x $sock
  384.     } else {
  385.         puts $sock hello
  386. flush $sock
  387.         lappend x [gets $f]
  388.         close $sock
  389.     }
  390.     close $f
  391.     set x
  392. } {ready hello}
  393. test socket-2.6 {tcp connection} {socket} {
  394.     set status ok
  395.     if {![catch {set sock [socket 127.0.0.1 2833]}]} {
  396. if {![catch {gets $sock}]} {
  397.     set status broken
  398. }
  399. close $sock
  400.     }
  401.     set status
  402. } ok
  403. test socket-2.7 {echo server, one line} {socket stdio} {
  404.     file delete $path(script)
  405.     set f [open $path(script) w]
  406.     puts $f {
  407. set timer [after 10000 "set x timeout"]
  408. set f [socket -server accept 0]
  409. proc accept {s a p} {
  410.             fileevent $s readable [list echo $s]
  411.     fconfigure $s -translation lf -buffering line
  412.         }
  413. proc echo {s} {
  414.      set l [gets $s]
  415.              if {[eof $s]} {
  416.                  global x
  417.                  close $s
  418.                  set x done
  419.              } else {
  420.                  puts $s $l
  421.              }
  422. }
  423. puts ready
  424. puts [lindex [fconfigure $f -sockname] 2]
  425. vwait x
  426. after cancel $timer
  427. close $f
  428. puts $x
  429.     }
  430.     close $f
  431.     set f [open "|[list [interpreter] $path(script)]" r]
  432.     gets $f
  433.     gets $f listen
  434.     set s [socket 127.0.0.1 $listen]
  435.     fconfigure $s -buffering line -translation lf
  436.     puts $s "hello abcdefghijklmnop"
  437.     after 1000
  438.     set x [gets $s]
  439.     close $s
  440.     set y [gets $f]
  441.     close $f
  442.     list $x $y
  443. } {{hello abcdefghijklmnop} done}
  444. removeFile script
  445. test socket-2.8 {echo server, loop 50 times, single connection} -constraints {socket stdio} -setup {
  446.     set path(script) [makeFile {
  447. set f [socket -server accept 0]
  448. proc accept {s a p} {
  449.             fileevent $s readable [list echo $s]
  450.             fconfigure $s -buffering line
  451.         }
  452. proc echo {s} {
  453.      global i
  454.              set l [gets $s]
  455.              if {[eof $s]} {
  456.                  global x
  457.                  close $s
  458.                  set x done
  459.              } else { 
  460.          incr i
  461.                  puts $s $l
  462.              }
  463. }
  464. set i 0
  465. puts ready
  466. puts [lindex [fconfigure $f -sockname] 2]
  467. set timer [after 20000 "set x done"]
  468. vwait x
  469. after cancel $timer
  470. close $f
  471. puts "done $i"
  472.     } script]
  473. } -body {
  474.     set f [open "|[list [interpreter] $path(script)]" r]
  475.     gets $f
  476.     gets $f listen
  477.     set s [socket 127.0.0.1 $listen]
  478.     fconfigure $s -buffering line
  479.     catch {
  480. for {set x 0} {$x < 50} {incr x} {
  481.     puts $s "hello abcdefghijklmnop"
  482.     gets $s
  483. }
  484.     }
  485.     close $s
  486.     catch {set x [gets $f]}
  487.     close $f
  488.     set x
  489. } -cleanup {
  490.     removeFile script
  491. } -result {done 50}
  492. set path(script) [makeFile {} script]
  493. test socket-2.9 {socket conflict} {socket stdio} {
  494.     set s [socket -server accept 0]
  495.     file delete $path(script)
  496.     set f [open $path(script) w]
  497.     puts -nonewline $f "socket -server accept [lindex [fconfigure $s -sockname] 2]"
  498.     close $f
  499.     set f [open "|[list [interpreter] $path(script)]" r]
  500.     gets $f
  501.     after 100
  502.     set x [list [catch {close $f} msg]]
  503.     regsub "n.*$" $msg {} msg ; # cut part of the error message containing the port number
  504.     lappend x $msg
  505.     close $s
  506.     set x
  507. } {1 {couldn't open socket: address already in use}}
  508. test socket-2.10 {close on accept, accepted socket lives} {socket} {
  509.     set done 0
  510.     set timer [after 20000 "set done timed_out"]
  511.     set ss [socket -server accept 0]
  512.     proc accept {s a p} {
  513. global ss
  514. close $ss
  515. fileevent $s readable "readit $s"
  516. fconfigure $s -trans lf
  517.     }
  518.     proc readit {s} {
  519. global done
  520. gets $s
  521. close $s
  522. set done 1
  523.     }
  524.     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  525.     puts $cs hello
  526.     close $cs
  527.     vwait done
  528.     after cancel $timer
  529.     set done
  530. } 1
  531. test socket-2.11 {detecting new data} {socket} {
  532.     proc accept {s a p} {
  533. global sock
  534. set sock $s
  535.     }
  536.     set s [socket -server accept 0]
  537.     set sock ""
  538.     set s2 [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  539.     vwait sock
  540.     puts $s2 one
  541.     flush $s2
  542.     after 500
  543.     fconfigure $sock -blocking 0
  544.     set result a:[gets $sock]
  545.     lappend result b:[gets $sock]
  546.     fconfigure $sock -blocking 1
  547.     puts $s2 two
  548.     flush $s2
  549.     fconfigure $sock -blocking 0
  550.     lappend result c:[gets $sock]
  551.     fconfigure $sock -blocking 1
  552.     close $s2
  553.     close $s
  554.     close $sock
  555.     set result
  556. } {a:one b: c:two}
  557. test socket-3.1 {socket conflict} {socket stdio} {
  558.     file delete $path(script)
  559.     set f [open $path(script) w]
  560.     puts $f {
  561. set f [socket -server accept 0]
  562. puts ready
  563. puts [lindex [fconfigure $f -sockname] 2]
  564. gets stdin
  565. close $f
  566.     }
  567.     close $f
  568.     set f [open "|[list [interpreter] $path(script)]" r+]
  569.     gets $f
  570.     gets $f listen
  571.     set x [list [catch {socket -server accept $listen} msg] 
  572. $msg]
  573.     puts $f bye
  574.     close $f
  575.     set x
  576. } {1 {couldn't open socket: address already in use}}
  577. test socket-3.2 {server with several clients} {socket stdio} {
  578.     file delete $path(script)
  579.     set f [open $path(script) w]
  580.     puts $f {
  581. set t1 [after 30000 "set x timed_out"]
  582. set t2 [after 31000 "set x timed_out"]
  583. set t3 [after 32000 "set x timed_out"]
  584. set counter 0
  585. set s [socket -server accept 0]
  586. proc accept {s a p} {
  587.     fileevent $s readable [list echo $s]
  588.     fconfigure $s -buffering line
  589. }
  590. proc echo {s} {
  591.      global x
  592.              set l [gets $s]
  593.              if {[eof $s]} {
  594.                  close $s
  595.                  set x done
  596.              } else {
  597.                  puts $s $l
  598.              }
  599. }
  600. puts ready
  601. puts [lindex [fconfigure $s -sockname] 2]
  602. vwait x
  603. after cancel $t1
  604. vwait x
  605. after cancel $t2
  606. vwait x
  607. after cancel $t3
  608. close $s
  609. puts $x
  610.     }
  611.     close $f
  612.     set f [open "|[list [interpreter] $path(script)]" r+]
  613.     set x [gets $f]
  614.     gets $f listen
  615.     set s1 [socket 127.0.0.1 $listen]
  616.     fconfigure $s1 -buffering line
  617.     set s2 [socket 127.0.0.1 $listen]
  618.     fconfigure $s2 -buffering line
  619.     set s3 [socket 127.0.0.1 $listen]
  620.     fconfigure $s3 -buffering line
  621.     for {set i 0} {$i < 100} {incr i} {
  622. puts $s1 hello,s1
  623. gets $s1
  624. puts $s2 hello,s2
  625. gets $s2
  626. puts $s3 hello,s3
  627. gets $s3
  628.     }
  629.     close $s1
  630.     close $s2
  631.     close $s3
  632.     lappend x [gets $f]
  633.     close $f
  634.     set x
  635. } {ready done}
  636. test socket-4.1 {server with several clients} {socket stdio} {
  637.     file delete $path(script)
  638.     set f [open $path(script) w]
  639.     puts $f {
  640. set port [gets stdin]
  641. set s [socket 127.0.0.1 $port]
  642. fconfigure $s -buffering line
  643. for {set i 0} {$i < 100} {incr i} {
  644.     puts $s hello
  645.     gets $s
  646. }
  647. close $s
  648. puts bye
  649. gets stdin
  650.     }
  651.     close $f
  652.     set p1 [open "|[list [interpreter] $path(script)]" r+]
  653.     fconfigure $p1 -buffering line
  654.     set p2 [open "|[list [interpreter] $path(script)]" r+]
  655.     fconfigure $p2 -buffering line
  656.     set p3 [open "|[list [interpreter] $path(script)]" r+]
  657.     fconfigure $p3 -buffering line
  658.     proc accept {s a p} {
  659. fconfigure $s -buffering line
  660. fileevent $s readable [list echo $s]
  661.     }
  662.     proc echo {s} {
  663. global x
  664.         set l [gets $s]
  665.         if {[eof $s]} {
  666.             close $s
  667.             set x done
  668.         } else {
  669.             puts $s $l
  670.         }
  671.     }
  672.     set t1 [after 30000 "set x timed_out"]
  673.     set t2 [after 31000 "set x timed_out"]
  674.     set t3 [after 32000 "set x timed_out"]
  675.     set s [socket -server accept 0]
  676.     set listen [lindex [fconfigure $s -sockname] 2]
  677.     puts $p1 $listen
  678.     puts $p2 $listen
  679.     puts $p3 $listen
  680.     vwait x
  681.     vwait x
  682.     vwait x
  683.     after cancel $t1
  684.     after cancel $t2
  685.     after cancel $t3
  686.     close $s
  687.     set l ""
  688.     lappend l [list p1 [gets $p1] $x]
  689.     lappend l [list p2 [gets $p2] $x]
  690.     lappend l [list p3 [gets $p3] $x]
  691.     puts $p1 bye
  692.     puts $p2 bye
  693.     puts $p3 bye
  694.     close $p1
  695.     close $p2
  696.     close $p3
  697.     set l
  698. } {{p1 bye done} {p2 bye done} {p3 bye done}}
  699. test socket-4.2 {byte order problems, socket numbers, htons} {socket} {
  700.     set x ok
  701.     if {[catch {socket -server dodo 0x3000} msg]} {
  702. set x $msg
  703.     } else {
  704. close $msg
  705.     }
  706.     set x
  707. } ok
  708. test socket-5.1 {byte order problems, socket numbers, htons} 
  709. {socket unixOnly notRoot} {
  710.     set x {couldn't open socket: not owner}
  711.     if {![catch {socket -server dodo 0x1} msg]} {
  712.         set x {htons problem, should be disallowed, are you running as SU?}
  713. close $msg
  714.     }
  715.     set x
  716. } {couldn't open socket: not owner}
  717. test socket-5.2 {byte order problems, socket numbers, htons} {socket} {
  718.     set x {couldn't open socket: port number too high}
  719.     if {![catch {socket -server dodo 0x10000} msg]} {
  720. set x {port resolution problem, should be disallowed}
  721. close $msg
  722.     }
  723.     set x
  724. } {couldn't open socket: port number too high}
  725. test socket-5.3 {byte order problems, socket numbers, htons} 
  726. {socket unixOnly notRoot} {
  727.     set x {couldn't open socket: not owner}
  728.     if {![catch {socket -server dodo 21} msg]} {
  729. set x {htons problem, should be disallowed, are you running as SU?}
  730. close $msg
  731.     }
  732.     set x
  733. } {couldn't open socket: not owner}
  734. test socket-6.1 {accept callback error} {socket stdio} {
  735.     file delete $path(script)
  736.     set f [open $path(script) w]
  737.     puts $f {
  738. gets stdin port
  739. socket 127.0.0.1 $port
  740.     }
  741.     close $f
  742.     set f [open "|[list [interpreter] $path(script)]" r+]
  743.     proc bgerror args {
  744. global x
  745. set x $args
  746.     }
  747.     proc accept {s a p} {expr 10 / 0}
  748.     set s [socket -server accept 0]
  749.     puts $f [lindex [fconfigure $s -sockname] 2]
  750.     close $f
  751.     set timer [after 10000 "set x timed_out"]
  752.     vwait x
  753.     after cancel $timer
  754.     close $s
  755.     rename bgerror {}
  756.     set x
  757. } {{divide by zero}}
  758. test socket-7.1 {testing socket specific options} {socket stdio} {
  759.     file delete $path(script)
  760.     set f [open $path(script) w]
  761.     puts $f {
  762. set ss [socket -server accept 0]
  763. proc accept args {
  764.     global x
  765.     set x done
  766. }
  767. puts ready
  768. puts [lindex [fconfigure $ss -sockname] 2]
  769. set timer [after 10000 "set x timed_out"]
  770. vwait x
  771. after cancel $timer
  772.     }
  773.     close $f
  774.     set f [open "|[list [interpreter] $path(script)]" r]
  775.     gets $f
  776.     gets $f listen
  777.     set s [socket 127.0.0.1 $listen]
  778.     set p [fconfigure $s -peername]
  779.     close $s
  780.     close $f
  781.     set l ""
  782.     lappend l [string compare [lindex $p 0] 127.0.0.1]
  783.     lappend l [string compare [lindex $p 2] $listen]
  784.     lappend l [llength $p]
  785. } {0 0 3}
  786. test socket-7.2 {testing socket specific options} {socket stdio} {
  787.     file delete $path(script)
  788.     set f [open $path(script) w]
  789.     puts $f {
  790. set ss [socket -server accept 2821]
  791. proc accept args {
  792.     global x
  793.     set x done
  794. }
  795. puts ready
  796. puts [lindex [fconfigure $ss -sockname] 2]
  797. set timer [after 10000 "set x timed_out"]
  798. vwait x
  799. after cancel $timer
  800.     }
  801.     close $f
  802.     set f [open "|[list [interpreter] $path(script)]" r]
  803.     gets $f
  804.     gets $f listen
  805.     set s [socket 127.0.0.1 $listen]
  806.     set p [fconfigure $s -sockname]
  807.     close $s
  808.     close $f
  809.     list [llength $p] 
  810.     [regexp {^(127.0.0.1|0.0.0.0)$} [lindex $p 0]] 
  811.     [expr {[lindex $p 2] == $listen}]
  812. } {3 1 0}
  813. test socket-7.3 {testing socket specific options} {socket} {
  814.     set s [socket -server accept 0]
  815.     set l [fconfigure $s]
  816.     close $s
  817.     update
  818.     llength $l
  819. } 14
  820. test socket-7.4 {testing socket specific options} {socket} {
  821.     set s [socket -server accept 0]
  822.     proc accept {s a p} {
  823. global x
  824. set x [fconfigure $s -sockname]
  825. close $s
  826.     }
  827.     set listen [lindex [fconfigure $s -sockname] 2]
  828.     set s1 [socket [info hostname] $listen]
  829.     set timer [after 10000 "set x timed_out"]
  830.     vwait x
  831.     after cancel $timer
  832.     close $s
  833.     close $s1
  834.     set l ""
  835.     lappend l [expr {[lindex $x 2] == $listen}] [llength $x]
  836. } {1 3}
  837. test socket-7.5 {testing socket specific options} {socket unixOrPc} {
  838.     set s [socket -server accept 0]
  839.     proc accept {s a p} {
  840. global x
  841. set x [fconfigure $s -sockname]
  842. close $s
  843.     }
  844.     set listen [lindex [fconfigure $s -sockname] 2]
  845.     set s1 [socket 127.0.0.1 $listen]
  846.     set timer [after 10000 "set x timed_out"]
  847.     vwait x
  848.     after cancel $timer
  849.     close $s
  850.     close $s1
  851.     set l ""
  852.     lappend l [lindex $x 0] [expr {[lindex $x 2] == $listen}] [llength $x]
  853. } {127.0.0.1 1 3}
  854. test socket-8.1 {testing -async flag on sockets} {socket} {
  855.     # NOTE: This test may fail on some Solaris 2.4 systems. If it does,
  856.     # check that you have these patches installed (using showrev -p):
  857.     #
  858.     # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
  859.     # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
  860.     # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
  861.     # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
  862.     # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
  863.     # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
  864.     #
  865.     # If after installing these patches you are still experiencing a
  866.     # problem, please email jyl@eng.sun.com. We have not observed this
  867.     # failure on Solaris 2.5, so another option (instead of installing
  868.     # these patches) is to upgrade to Solaris 2.5.
  869.     set s [socket -server accept 0]
  870.     proc accept {s a p} {
  871. global x
  872. puts $s bye
  873. close $s
  874. set x done
  875.     }
  876.     set s1 [socket -async [info hostname] [lindex [fconfigure $s -sockname] 2]]
  877.     vwait x
  878.     set z [gets $s1]
  879.     close $s
  880.     close $s1
  881.     set z
  882. } bye
  883. test socket-9.1 {testing spurious events} {socket} {
  884.     set len 0
  885.     set spurious 0
  886.     set done 0
  887.     proc readlittle {s} {
  888. global spurious done len
  889. set l [read $s 1]
  890. if {[string length $l] == 0} {
  891.     if {![eof $s]} {
  892. incr spurious
  893.     } else {
  894. close $s
  895. set done 1
  896.     }
  897. } else {
  898.     incr len [string length $l]
  899. }
  900.     }
  901.     proc accept {s a p} {
  902. fconfigure $s -buffering none -blocking off
  903. fileevent $s readable [list readlittle $s]
  904.     }
  905.     set s [socket -server accept 0]
  906.     set c [socket [info hostname] [lindex [fconfigure $s -sockname] 2]]
  907.     puts -nonewline $c 01234567890123456789012345678901234567890123456789
  908.     close $c
  909.     set timer [after 10000 "set done timed_out"]
  910.     vwait done
  911.     after cancel $timer
  912.     close $s
  913.     list $spurious $len
  914. } {0 50}
  915. test socket-9.2 {testing async write, fileevents, flush on close} {socket} {
  916.     set firstblock ""
  917.     for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
  918.     set secondblock ""
  919.     for {set i 0} {$i < 16} {incr i} {
  920. set secondblock "b$secondblock$secondblock"
  921.     }
  922.     set l [socket -server accept 0]
  923.     proc accept {s a p} {
  924. fconfigure $s -blocking 0 -translation lf -buffersize 16384 
  925. -buffering line
  926. fileevent $s readable "readable $s"
  927.     }
  928.     proc readable {s} {
  929. set l [gets $s]
  930. fileevent $s readable {}
  931. after 1000 respond $s
  932.     }
  933.     proc respond {s} {
  934. global firstblock
  935. puts -nonewline $s $firstblock
  936. after 1000 writedata $s
  937.     }
  938.     proc writedata {s} {
  939. global secondblock
  940. puts -nonewline $s $secondblock
  941. close $s
  942.     }
  943.     set s [socket [info hostname] [lindex [fconfigure $l -sockname] 2]]
  944.     fconfigure $s -blocking 0 -trans lf -buffering line
  945.     set count 0
  946.     puts $s hello
  947.     proc readit {s} {
  948. global count done
  949. set l [read $s]
  950. incr count [string length $l]
  951. if {[eof $s]} {
  952.     close $s
  953.     set done 1
  954. }
  955.     }
  956.     fileevent $s readable "readit $s"
  957.     set timer [after 10000 "set done timed_out"]
  958.     vwait done
  959.     after cancel $timer
  960.     close $l
  961.     set count
  962. } 65566
  963. test socket-9.3 {testing EOF stickyness} {socket} {
  964.     proc count_to_eof {s} {
  965. global count done timer
  966. set l [gets $s]
  967. if {[eof $s]} {
  968.     incr count
  969.     if {$count > 9} {
  970. close $s
  971. set done true
  972. set count {eof is sticky}
  973. after cancel $timer
  974.     }
  975. }
  976.     }
  977.     proc timerproc {} {
  978. global done count c
  979. set done true
  980. set count {timer went off, eof is not sticky}
  981. close $c
  982.     }
  983.     set count 0
  984.     set done false
  985.     proc write_then_close {s} {
  986. puts $s bye
  987. close $s
  988.     }
  989.     proc accept {s a p} {
  990. fconfigure $s -buffering line -translation lf
  991. fileevent $s writable "write_then_close $s"
  992.     }
  993.     set s [socket -server accept 0]
  994.     set c [socket [info hostname] [lindex [fconfigure $s -sockname] 2]]
  995.     fconfigure $c -blocking off -buffering line -translation lf
  996.     fileevent $c readable "count_to_eof $c"
  997.     set timer [after 1000 timerproc]
  998.     vwait done
  999.     close $s
  1000.     set count
  1001. } {eof is sticky}
  1002. removeFile script
  1003. test socket-10.1 {testing socket accept callback error handling} {socket} {
  1004.     set goterror 0
  1005.     proc bgerror args {global goterror; set goterror 1}
  1006.     set s [socket -server accept 0]
  1007.     proc accept {s a p} {close $s; error}
  1008.     set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  1009.     vwait goterror
  1010.     close $s
  1011.     close $c
  1012.     set goterror
  1013. } 1
  1014. test socket-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
  1015.     sendCommand {
  1016. set socket9_1_test_server [socket -server accept 2834]
  1017. proc accept {s a p} {
  1018.     puts $s done
  1019.     close $s
  1020. }
  1021.     }
  1022.     set s [socket $remoteServerIP 2834]
  1023.     set r [gets $s]
  1024.     close $s
  1025.     sendCommand {close $socket9_1_test_server}
  1026.     set r
  1027. } done
  1028. test socket-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
  1029.     if {[info exists port]} {
  1030. incr port
  1031.     } else {
  1032. set port [expr 2048 + [pid]%1024]
  1033.     }
  1034.     sendCommand {
  1035. set socket9_2_test_server [socket -server accept 2835]
  1036. proc accept {s a p} {
  1037.     puts $s $p
  1038.     close $s
  1039. }
  1040.     }
  1041.     set s [socket -myport $port $remoteServerIP 2835]
  1042.     set r [gets $s]
  1043.     close $s
  1044.     sendCommand {close $socket9_2_test_server}
  1045.     if {$r == $port} {
  1046. set result ok
  1047.     } else {
  1048. set result broken
  1049.     }
  1050.     set result
  1051. } ok
  1052. test socket-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
  1053.     set status ok
  1054.     if {![catch {set s [socket $remoteServerIp 2836]}]} {
  1055. if {![catch {gets $s}]} {
  1056.     set status broken
  1057. }
  1058. close $s
  1059.     }
  1060.     set status
  1061. } ok
  1062. test socket-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
  1063.     sendCommand {
  1064. set socket10_6_test_server [socket -server accept 2836]
  1065. proc accept {s a p} {
  1066.     fileevent $s readable [list echo $s]
  1067.     fconfigure $s -buffering line -translation crlf
  1068. }
  1069. proc echo {s} {
  1070.     set l [gets $s]
  1071.     if {[eof $s]} {
  1072. close $s
  1073.     } else {
  1074. puts $s $l
  1075.     }
  1076. }
  1077.     }
  1078.     set f [socket $remoteServerIP 2836]
  1079.     fconfigure $f -translation crlf -buffering line
  1080.     puts $f hello
  1081.     set r [gets $f]
  1082.     close $f
  1083.     sendCommand {close $socket10_6_test_server}
  1084.     set r
  1085. } hello
  1086. test socket-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
  1087.     sendCommand {
  1088. set socket10_7_test_server [socket -server accept 2836]
  1089. proc accept {s a p} {
  1090.     fileevent $s readable [list echo $s]
  1091.     fconfigure $s -buffering line -translation crlf
  1092. }
  1093. proc echo {s} {
  1094.     set l [gets $s]
  1095.     if {[eof $s]} {
  1096. close $s
  1097.     } else {
  1098. puts $s $l
  1099.     }
  1100. }
  1101.     }
  1102.     set f [socket $remoteServerIP 2836]
  1103.     fconfigure $f -translation crlf -buffering line
  1104.     for {set cnt 0} {$cnt < 50} {incr cnt} {
  1105. puts $f "hello, $cnt"
  1106. if {[string compare [gets $f] "hello, $cnt"] != 0} {
  1107.     break
  1108. }
  1109.     }
  1110.     close $f
  1111.     sendCommand {close $socket10_7_test_server}
  1112.     set cnt
  1113. } 50
  1114. # Macintosh sockets can have more than one server per port
  1115. if {$tcl_platform(platform) == "macintosh"} {
  1116.     set conflictResult {0 2836}
  1117. } else {
  1118.     set conflictResult {1 {couldn't open socket: address already in use}}
  1119. }
  1120. test socket-11.6 {socket conflict} {socket doTestsWithRemoteServer} {
  1121.     set s1 [socket -server accept 2836]
  1122.     if {[catch {set s2 [socket -server accept 2836]} msg]} {
  1123. set result [list 1 $msg]
  1124.     } else {
  1125. set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
  1126. close $s2
  1127.     }
  1128.     close $s1
  1129.     set result
  1130. } $conflictResult
  1131. test socket-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
  1132.     sendCommand {
  1133. set socket10_9_test_server [socket -server accept 2836]
  1134. proc accept {s a p} {
  1135.     fconfigure $s -buffering line
  1136.     fileevent $s readable [list echo $s]
  1137. }
  1138. proc echo {s} {
  1139.     set l [gets $s]
  1140.     if {[eof $s]} {
  1141. close $s
  1142.     } else {
  1143. puts $s $l
  1144.     }
  1145. }
  1146.     }
  1147.     set s1 [socket $remoteServerIP 2836]
  1148.     fconfigure $s1 -buffering line
  1149.     set s2 [socket $remoteServerIP 2836]
  1150.     fconfigure $s2 -buffering line
  1151.     set s3 [socket $remoteServerIP 2836]
  1152.     fconfigure $s3 -buffering line
  1153.     for {set i 0} {$i < 100} {incr i} {
  1154. puts $s1 hello,s1
  1155. gets $s1
  1156. puts $s2 hello,s2
  1157. gets $s2
  1158. puts $s3 hello,s3
  1159. gets $s3
  1160.     }
  1161.     close $s1
  1162.     close $s2
  1163.     close $s3
  1164.     sendCommand {close $socket10_9_test_server}
  1165.     set i
  1166. } 100    
  1167. test socket-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
  1168.     sendCommand {
  1169. set s1 [socket -server "accept 4003" 4003]
  1170. set s2 [socket -server "accept 4004" 4004]
  1171. set s3 [socket -server "accept 4005" 4005]
  1172. proc accept {mp s a p} {
  1173.     puts $s $mp
  1174.     close $s
  1175. }
  1176.     }
  1177.     set s1 [socket $remoteServerIP 4003]
  1178.     set s2 [socket $remoteServerIP 4004]
  1179.     set s3 [socket $remoteServerIP 4005]
  1180.     set l ""
  1181.     lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] 
  1182. [gets $s3] [gets $s3] [eof $s3]
  1183.     close $s1
  1184.     close $s2
  1185.     close $s3
  1186.     sendCommand {
  1187. close $s1
  1188. close $s2
  1189. close $s3
  1190.     }
  1191.     set l
  1192. } {4003 {} 1 4004 {} 1 4005 {} 1}
  1193. test socket-11.9 {accept callback error} {socket doTestsWithRemoteServer} {
  1194.     set s [socket -server accept 2836]
  1195.     proc accept {s a p} {expr 10 / 0}
  1196.     proc bgerror args {
  1197. global x
  1198. set x $args
  1199.     }
  1200.     if {[catch {sendCommand {
  1201.     set peername [fconfigure $callerSocket -peername]
  1202.     set s [socket [lindex $peername 0] 2836]
  1203.     close $s
  1204.       }} msg]} {
  1205. close $s
  1206. error $msg
  1207.     }
  1208.     set timer [after 10000 "set x timed_out"]
  1209.     vwait x
  1210.     after cancel $timer
  1211.     close $s
  1212.     rename bgerror {}
  1213.     set x
  1214. } {{divide by zero}}
  1215. test socket-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
  1216.     sendCommand {
  1217. set socket10_12_test_server [socket -server accept 2836]
  1218. proc accept {s a p} {close $s}
  1219.     }
  1220.     set s [socket $remoteServerIP 2836]
  1221.     set p [fconfigure $s -peername]
  1222.     set n [fconfigure $s -sockname]
  1223.     set l ""
  1224.     lappend l [lindex $p 2] [llength $p] [llength $p]
  1225.     close $s
  1226.     sendCommand {close $socket10_12_test_server}
  1227.     set l
  1228. } {2836 3 3}
  1229. test socket-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
  1230.     sendCommand {
  1231. set socket10_13_test_server [socket -server accept 2836]
  1232. proc accept {s a p} {
  1233.     fconfigure $s -translation "auto lf"
  1234.     after 100 writesome $s
  1235. }
  1236. proc writesome {s} {
  1237.     for {set i 0} {$i < 100} {incr i} {
  1238. puts $s "line $i from remote server"
  1239.     }
  1240.     close $s
  1241. }
  1242.     }
  1243.     set len 0
  1244.     set spurious 0
  1245.     set done 0
  1246.     proc readlittle {s} {
  1247. global spurious done len
  1248. set l [read $s 1]
  1249. if {[string length $l] == 0} {
  1250.     if {![eof $s]} {
  1251. incr spurious
  1252.     } else {
  1253. close $s
  1254. set done 1
  1255.     }
  1256. } else {
  1257.     incr len [string length $l]
  1258. }
  1259.     }
  1260.     set c [socket $remoteServerIP 2836]
  1261.     fileevent $c readable "readlittle $c"
  1262.     set timer [after 40000 "set done timed_out"]
  1263.     vwait done
  1264.     after cancel $timer
  1265.     sendCommand {close $socket10_13_test_server}
  1266.     list $spurious $len $done
  1267. } {0 2690 1}
  1268. test socket-11.12 {testing EOF stickyness} {socket doTestsWithRemoteServer} {
  1269.     set counter 0
  1270.     set done 0
  1271.     proc count_up {s} {
  1272. global counter done after_id
  1273. set l [gets $s]
  1274. if {[eof $s]} {
  1275.     incr counter
  1276.     if {$counter > 9} {
  1277. set done {EOF is sticky}
  1278. after cancel $after_id
  1279. close $s
  1280.     }
  1281. }
  1282.     }
  1283.     proc timed_out {} {
  1284. global c done
  1285. set done {timed_out, EOF is not sticky}
  1286. close $c
  1287.     }
  1288.     sendCommand {
  1289. set socket10_14_test_server [socket -server accept 2836]
  1290. proc accept {s a p} {
  1291.     after 100 close $s
  1292. }
  1293.     }
  1294.     set c [socket $remoteServerIP 2836]
  1295.     fileevent $c readable [list count_up $c]
  1296.     set after_id [after 1000 timed_out]
  1297.     vwait done
  1298.     sendCommand {close $socket10_14_test_server}
  1299.     set done
  1300. } {EOF is sticky}
  1301. test socket-11.13 {testing async write, async flush, async close} 
  1302. {socket doTestsWithRemoteServer} {
  1303.     proc readit {s} {
  1304. global count done
  1305. set l [read $s]
  1306. incr count [string length $l]
  1307. if {[eof $s]} {
  1308.     close $s
  1309.     set done 1
  1310. }
  1311.     }
  1312.     sendCommand {
  1313. set firstblock ""
  1314. for {set i 0} {$i < 5} {incr i} {
  1315. set firstblock "a$firstblock$firstblock"
  1316. }
  1317. set secondblock ""
  1318. for {set i 0} {$i < 16} {incr i} {
  1319.     set secondblock "b$secondblock$secondblock"
  1320. }
  1321. set l [socket -server accept 2845]
  1322. proc accept {s a p} {
  1323.     fconfigure $s -blocking 0 -translation lf -buffersize 16384 
  1324. -buffering line
  1325.     fileevent $s readable "readable $s"
  1326. }
  1327. proc readable {s} {
  1328.     set l [gets $s]
  1329.     fileevent $s readable {}
  1330.     after 1000 respond $s
  1331. }
  1332. proc respond {s} {
  1333.     global firstblock
  1334.     puts -nonewline $s $firstblock
  1335.     after 1000 writedata $s
  1336. }
  1337. proc writedata {s} {
  1338.     global secondblock
  1339.     puts -nonewline $s $secondblock
  1340.     close $s
  1341. }
  1342.     }
  1343.     set s [socket $remoteServerIP 2845]
  1344.     fconfigure $s -blocking 0 -trans lf -buffering line
  1345.     set count 0
  1346.     puts $s hello
  1347.     fileevent $s readable "readit $s"
  1348.     set timer [after 10000 "set done timed_out"]
  1349.     vwait done
  1350.     after cancel $timer
  1351.     sendCommand {close $l}
  1352.     set count
  1353. } 65566
  1354. set path(script1) [makeFile {} script1]
  1355. set path(script2) [makeFile {} script2]
  1356. test socket-12.1 {testing inheritance of server sockets} {socket stdio exec} {
  1357.     file delete $path(script1)
  1358.     file delete $path(script2)
  1359.     # Script1 is just a 10 second delay.  If the server socket
  1360.     # is inherited, it will be held open for 10 seconds
  1361.     set f [open $path(script1) w]
  1362.     puts $f {
  1363. after 10000 exit
  1364. vwait forever
  1365.     }
  1366.     close $f
  1367.     # Script2 creates the server socket, launches script1,
  1368.     # waits a second, and exits.  The server socket will now
  1369.     # be closed unless script1 inherited it.
  1370.     set f [open $path(script2) w]
  1371.     puts $f [list set tcltest [interpreter]]
  1372.     puts -nonewline $f {
  1373. set f [socket -server accept 0]
  1374. puts [lindex [fconfigure $f -sockname] 2]
  1375. proc accept { file addr port } {
  1376.     close $file
  1377. }
  1378. exec $tcltest }
  1379.     puts $f [list $path(script1) &]
  1380.     puts $f {
  1381. close $f
  1382. after 1000 exit
  1383. vwait forever
  1384.     }
  1385.     close $f
  1386.     # Launch script2 and wait 5 seconds
  1387.     ### exec [interpreter] script2 &
  1388.     set p [open "|[list [interpreter] $path(script2)]" r]
  1389.     gets $p listen
  1390.     after 5000 { set ok_to_proceed 1 }
  1391.     vwait ok_to_proceed
  1392.     # If we can still connect to the server, the socket got inherited.
  1393.     if {[catch {socket 127.0.0.1 $listen} msg]} {
  1394. set x {server socket was not inherited}
  1395.     } else {
  1396. close $msg
  1397. set x {server socket was inherited}
  1398.     }
  1399.     close $p
  1400.     set x
  1401. } {server socket was not inherited}
  1402. test socket-12.2 {testing inheritance of client sockets} {socket stdio exec} {
  1403.     file delete $path(script1)
  1404.     file delete $path(script2)
  1405.     # Script1 is just a 20 second delay.  If the server socket
  1406.     # is inherited, it will be held open for 10 seconds
  1407.     set f [open $path(script1) w]
  1408.     puts $f {
  1409. after 20000 exit
  1410. vwait forever
  1411.     }
  1412.     close $f
  1413.     # Script2 opens the client socket and writes to it.  It then
  1414.     # launches script1 and exits.  If the child process inherited the
  1415.     # client socket, the socket will still be open.
  1416.     set f [open $path(script2) w]
  1417.     puts $f [list set tcltest [interpreter]]
  1418.     puts -nonewline $f {
  1419.         gets stdin port
  1420. set f [socket 127.0.0.1 $port]
  1421.         exec $tcltest }
  1422.     puts $f [list $path(script1) &]
  1423.     puts $f {
  1424. puts $f testing
  1425. flush $f
  1426. after 1000 exit
  1427. vwait forever
  1428.     }
  1429.     close $f
  1430.     # Create the server socket
  1431.     set server [socket -server accept 0]
  1432.     proc accept { file host port } {
  1433. # When the client connects, establish the read handler
  1434. global server
  1435. close $server
  1436. fileevent $file readable [list getdata $file]
  1437. fconfigure $file -buffering line -blocking 0
  1438. return
  1439.     }
  1440.     proc getdata { file } {
  1441. # Read handler on the accepted socket.
  1442. global x
  1443. global failed
  1444. set status [catch {read $file} data]
  1445. if {$status != 0} {
  1446.     set x {read failed, error was $data}
  1447.     catch { close $file }
  1448. } elseif {[string compare {} $data]} {
  1449. } elseif {[fblocked $file]} {
  1450. } elseif {[eof $file]} {
  1451.     if {$failed} {
  1452. set x {client socket was inherited}
  1453.     } else {
  1454. set x {client socket was not inherited}
  1455.     }
  1456.     catch { close $file }
  1457. } else {
  1458.     set x {impossible case}
  1459.     catch { close $file }
  1460. }
  1461. return
  1462.     }
  1463.     # If the socket doesn't hit end-of-file in 10 seconds, the
  1464.     # script1 process must have inherited the client.
  1465.     set failed 0
  1466.     after 10000 [list set failed 1]
  1467.     # Launch the script2 process
  1468.     ### exec [interpreter] script2 &
  1469.     set p [open "|[list [interpreter] $path(script2)]" w]
  1470.     puts $p [lindex [fconfigure $server -sockname] 2] ; flush $p
  1471.     vwait x
  1472.     if {!$failed} {
  1473. vwait failed
  1474.     }
  1475.     close $p
  1476.     set x
  1477. } {client socket was not inherited}
  1478. test socket-12.3 {testing inheritance of accepted sockets} {socket stdio exec} {
  1479.     file delete $path(script1)
  1480.     file delete $path(script2)
  1481.     set f [open $path(script1) w]
  1482.     puts $f {
  1483. after 10000 exit
  1484. vwait forever
  1485.     }
  1486.     close $f
  1487.     set f [open $path(script2) w]
  1488.     puts $f [list set tcltest [interpreter]]
  1489.     puts -nonewline $f {
  1490. set server [socket -server accept 0]
  1491. puts stdout [lindex [fconfigure $server -sockname] 2]
  1492. proc accept { file host port } }
  1493.     puts $f {
  1494.     puts -nonewline $f {
  1495.     global tcltest
  1496.     puts $file {test data on socket}
  1497.     exec $tcltest }
  1498.     puts $f [list $path(script1) &]
  1499.     puts $f {
  1500.     after 1000 exit
  1501. }
  1502.     puts $f } 
  1503.     puts $f {
  1504. vwait forever
  1505.     }
  1506.     close $f
  1507.     # Launch the script2 process and connect to it.  See how long
  1508.     # the socket stays open
  1509.     ## exec [interpreter] script2 &
  1510.     set p [open "|[list [interpreter] $path(script2)]" r]
  1511.     gets $p listen
  1512.     after 1000 set ok_to_proceed 1
  1513.     vwait ok_to_proceed
  1514.     set f [socket 127.0.0.1 $listen]
  1515.     fconfigure $f -buffering full -blocking 0
  1516.     fileevent $f readable [list getdata $f]
  1517.     # If the socket is still open after 5 seconds, the script1 process
  1518.     # must have inherited the accepted socket.
  1519.     set failed 0
  1520.     after 5000 set failed 1
  1521.     proc getdata { file } {
  1522. # Read handler on the client socket.
  1523. global x
  1524. global failed
  1525. set status [catch {read $file} data]
  1526. if {$status != 0} {
  1527.     set x {read failed, error was $data}
  1528.     catch { close $file }
  1529. } elseif {[string compare {} $data]} {
  1530. } elseif {[fblocked $file]} {
  1531. } elseif {[eof $file]} {
  1532.     if {$failed} {
  1533. set x {accepted socket was inherited}
  1534.     } else {
  1535. set x {accepted socket was not inherited}
  1536.     }
  1537.     catch { close $file }
  1538. } else {
  1539.     set x {impossible case}
  1540.     catch { close $file }
  1541. }
  1542. return
  1543.     }
  1544.     
  1545.     vwait x
  1546.     close $p
  1547.     set x
  1548. } {accepted socket was not inherited}
  1549. test socket-13.1 {Testing use of shared socket between two threads} 
  1550. -constraints {socket testthread} -setup {
  1551.     threadReap
  1552.     set path(script) [makeFile {
  1553. set f [socket -server accept 0]
  1554. set listen [lindex [fconfigure $f -sockname] 2]
  1555. proc accept {s a p} {
  1556.             fileevent $s readable [list echo $s]
  1557.             fconfigure $s -buffering line
  1558.         }
  1559. proc echo {s} {
  1560.      global i
  1561.              set l [gets $s]
  1562.              if {[eof $s]} {
  1563.                  global x
  1564.                  close $s
  1565.                  set x done
  1566.              } else { 
  1567.          incr i
  1568.                  puts $s $l
  1569.              }
  1570. }
  1571. set i 0
  1572. vwait x
  1573. close $f
  1574. # thread cleans itself up.
  1575. testthread exit
  1576.     } script]
  1577. } -body {
  1578.     # create a thread
  1579.     set serverthread [testthread create [list source $path(script) ] ]
  1580.     update
  1581.     set port [testthread send $serverthread {set listen}]
  1582.     update
  1583.     after 1000
  1584.     set s [socket 127.0.0.1 $port]
  1585.     fconfigure $s -buffering line
  1586.     catch {
  1587. puts $s "hello"
  1588. gets $s result
  1589.     }
  1590.     close $s
  1591.     update
  1592.     after 2000
  1593.     lappend result [threadReap]
  1594. } -cleanup {
  1595.     removeFile script
  1596. } -result {hello 1}
  1597. removeFile script1
  1598. removeFile script2
  1599. # cleanup
  1600. if {[string match sock* $commandSocket] == 1} {
  1601.    puts $commandSocket exit
  1602.    flush $commandSocket
  1603. }
  1604. catch {close $commandSocket}
  1605. catch {close $remoteProcChan}
  1606. ::tcltest::cleanupTests
  1607. flush stdout
  1608. return