3 # sanity tests for socket functions
7 @INC = '../lib' if -d '../lib' && -d '../ext';
10 require Config; import Config;
12 skip_all_if_miniperl();
13 for my $needed (qw(d_socket d_getpbyname)) {
14 if ($Config{$needed} ne 'define') {
15 skip_all("-- \$Config{$needed} undefined");
18 unless ($Config{extensions} =~ /\bSocket\b/) {
19 skip_all('-- Socket not available');
26 $| = 1; # ensure test output is synchronous so processes don't conflict
28 my $tcp = getprotobyname('tcp')
29 or skip_all("no tcp protocol available ($!)");
30 my $udp = getprotobyname('udp')
31 or note "getprotobyname('udp') failed: $!";
33 my $local = gethostbyname('localhost')
34 or note "gethostbyname('localhost') failed: $!";
36 my $fork = $Config{d_fork} || $Config{d_pseudofork};
39 # basic socket creation
40 socket(my $sock, PF_INET, SOCK_STREAM, $tcp)
41 or skip_all('socket() for tcp failed ($!), nothing else will work');
42 ok(close($sock), "close the socket");
47 $local or skip("No localhost", 2);
49 ok(socket(my $serv, PF_INET, SOCK_STREAM, $tcp), "make a tcp socket");
50 my $bind_at = pack_sockaddr_in(0, $local);
51 ok(bind($serv, $bind_at), "bind works")
52 or skip("Couldn't bind to localhost", 3);
53 my $bind_name = getsockname($serv);
54 ok($bind_name, "getsockname() on bound socket");
55 my ($bind_port) = unpack_sockaddr_in($bind_name);
57 print "# port $bind_port\n";
61 ok(listen($serv, 5), "listen() works")
62 or diag "listen error: $!";
64 $fork or skip("No fork", 1);
66 my $send_data = "test" x 50_000;
69 ok(socket(my $accept, PF_INET, SOCK_STREAM, $tcp),
70 "make accept tcp socket");
71 ok(my $addr = accept($accept, $serv), "accept() works")
72 or diag "accept error: $!";
75 while ($sent_total < length $send_data) {
76 my $sent = send($accept, substr($send_data, $sent_total), 0);
77 defined $sent or last;
80 my $shutdown = shutdown($accept, 1);
82 # wait for the remote to close so data isn't lost in
83 # transit on a certain broken implementation
85 # child tests are printed once we hit eof
86 curr_test(curr_test()+5);
89 ok($shutdown, "shutdown() works");
91 elsif (defined $pid) {
92 curr_test(curr_test()+2);
95 ok_child(close($serv), "close server socket in child");
96 ok_child(socket(my $child, PF_INET, SOCK_STREAM, $tcp),
97 "make child tcp socket");
99 ok_child(connect($child, $bind_name), "connect() works")
100 or diag "connect error: $!";
103 my $recv_peer = recv($child, $buf, 1000, 0);
107 $TODO = "[perl #122657] Hurd doesn't populate sin_len correctly"
110 ok_child($recv_peer eq '' || $recv_peer eq getpeername $child,
111 "peer from recv() should be empty or the remote name");
113 while(defined recv($child, my $tmp, 1000, 0)) {
114 last if length $tmp == 0;
117 is_child($buf, $send_data, "check we received the data");
125 diag "fork() failed $!";
126 skip("fork() failed", 1);
135 my ($ok, $note) = @_;
136 push @child_tests, ( $ok ? "ok " : "not ok ") . curr_test() . " - $note "
137 . ( $TODO ? "# TODO $TODO" : "" ) . "\n";
138 curr_test(curr_test()+1);
142 my ($got, $want, $note) = @_;
143 ok_child($got eq $want, $note);