PageRenderTime 68ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/tcl/tests/socket.test

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