This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(perl #128095) check pack_sockaddr_un()'s return value
[perl5.git] / dist / IO / t / cachepropagate-unix.t
CommitLineData
93a5d7bf
TC
1#!/usr/bin/perl
2
3use warnings;
4use strict;
5
6use File::Temp qw(tempdir);
7use File::Spec::Functions;
8use IO::Socket;
9use IO::Socket::UNIX;
10use Socket;
11use Config;
12use Test::More;
13
14plan skip_all => "UNIX domain sockets not implemented on $^O"
099fcb99 15 if ($^O =~ m/^(?:qnx|nto|vos|MSWin32|VMS)$/);
93a5d7bf 16
93a5d7bf
TC
17my $socketpath = catfile(tempdir( CLEANUP => 1 ), 'testsock');
18
5b549d1d
TC
19# check the socketpath fits in sun_path.
20#
21# pack_sockaddr_un() just truncates the path, this may change, but how
22# it will handle such a condition is undetermined (and we might need
23# to work with older versions of Socket outside of a perl build)
24# https://rt.cpan.org/Ticket/Display.html?id=116819
25
26my $name = eval { pack_sockaddr_un($socketpath) };
27defined $name && (unpack_sockaddr_un($name))[0] eq $socketpath
28 or plan skip_all => "socketpath too long for sockaddr_un";
29
30plan tests => 15;
31
93a5d7bf
TC
32# start testing stream sockets:
33my $listener = IO::Socket::UNIX->new(Type => SOCK_STREAM,
34 Listen => 1,
35 Local => $socketpath);
36ok(defined($listener), 'stream socket created');
37
38my $p = $listener->protocol();
39ok(defined($p), 'protocol defined');
40my $d = $listener->sockdomain();
41ok(defined($d), 'domain defined');
42my $s = $listener->socktype();
43ok(defined($s), 'type defined');
44
45SKIP: {
46 skip "fork not available", 4
47 unless $Config{d_fork} || $Config{d_pseudofork};
48
49 my $cpid = fork();
50 if (0 == $cpid) {
51 # the child:
52 sleep(1);
53 my $connector = IO::Socket::UNIX->new(Peer => $socketpath);
54 exit(0);
55 } else {
56 ok(defined($cpid), 'spawned a child');
57 }
58
59 my $new = $listener->accept();
60
93a5d7bf
TC
61 is($new->sockdomain(), $d, 'domain match');
62 SKIP: {
63 skip "no Socket::SO_PROTOCOL", 1 if !defined(eval { Socket::SO_PROTOCOL });
92fd341d
FP
64 skip "SO_PROTOCOL defined but not implemented", 1
65 if !defined $new->sockopt(Socket::SO_PROTOCOL);
93a5d7bf
TC
66 is($new->protocol(), $p, 'protocol match');
67 }
68 SKIP: {
69 skip "no Socket::SO_TYPE", 1 if !defined(eval { Socket::SO_TYPE });
92fd341d
FP
70 skip "SO_TYPE defined but not implemented", 1
71 if !defined $new->sockopt(Socket::SO_TYPE);
93a5d7bf
TC
72 is($new->socktype(), $s, 'type match');
73 }
74
75 unlink($socketpath);
76 wait();
77}
78
79undef $TODO;
93a5d7bf 80SKIP: {
4e1acb29
TC
81 skip "datagram unix sockets not supported on $^O", 7
82 if $^O eq "haiku";
83 # now test datagram sockets:
84 $listener = IO::Socket::UNIX->new(Type => SOCK_DGRAM,
85 Local => $socketpath);
86 ok(defined($listener), 'datagram socket created');
87
88 $p = $listener->protocol();
89 ok(defined($p), 'protocol defined');
90 $d = $listener->sockdomain();
91 ok(defined($d), 'domain defined');
92 $s = $listener->socktype();
93 ok(defined($s), 'type defined');
94
95 my $new = IO::Socket::UNIX->new_from_fd($listener->fileno(), 'r+');
96
97 is($new->sockdomain(), $d, 'domain match');
98 SKIP: {
99 skip "no Socket::SO_PROTOCOL", 1 if !defined(eval { Socket::SO_PROTOCOL });
92fd341d
FP
100 skip "SO_PROTOCOL defined but not implemented", 1
101 if !defined $new->sockopt(Socket::SO_PROTOCOL);
4e1acb29
TC
102 is($new->protocol(), $p, 'protocol match');
103 }
104 SKIP: {
610996fd
TC
105 skip "AIX: getsockopt(SO_TYPE) is badly broken on UDP/UNIX sockets", 1
106 if $^O eq "aix";
4e1acb29 107 skip "no Socket::SO_TYPE", 1 if !defined(eval { Socket::SO_TYPE });
92fd341d
FP
108 skip "SO_TYPE defined but not implemented", 1
109 if !defined $new->sockopt(Socket::SO_TYPE);
4e1acb29
TC
110 is($new->socktype(), $s, 'type match');
111 }
93a5d7bf
TC
112}
113unlink($socketpath);