xref: /openbsd-src/gnu/usr.bin/perl/dist/IO/t/io_unix.t (revision 256a93a44f36679bee503f12e49566c2183f6181)
1b39c5158Smillert#!./perl
2b39c5158Smillert
3b39c5158Smillertuse Config;
4de8cc8edSafresh1use IO::Socket;
5b39c5158Smillert
6b39c5158SmillertBEGIN {
7b39c5158Smillert    my $reason;
8de8cc8edSafresh1    my $can_fork = $Config{d_fork} ||
9de8cc8edSafresh1		    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
10de8cc8edSafresh1		     $Config{useithreads} and
11de8cc8edSafresh1		     $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/
12de8cc8edSafresh1		    );
13de8cc8edSafresh1
14b39c5158Smillert    if ($ENV{PERL_CORE} and $Config{'extensions'} !~ /\bSocket\b/) {
15b39c5158Smillert	$reason = 'Socket extension unavailable';
16b39c5158Smillert    }
17b39c5158Smillert    elsif ($ENV{PERL_CORE} and $Config{'extensions'} !~ /\bIO\b/) {
18b39c5158Smillert	$reason = 'IO extension unavailable';
19b39c5158Smillert    }
20b39c5158Smillert    elsif ($^O eq 'os2') {
21b39c5158Smillert	eval {IO::Socket::pack_sockaddr_un('/foo/bar') || 1}
22b39c5158Smillert	  or $@ !~ /not implemented/ or
23b39c5158Smillert	    $reason = 'compiled without TCP/IP stack v4';
24b39c5158Smillert    }
25de8cc8edSafresh1    elsif ($^O =~ m/^(?:qnx|nto|vos)$/ ) {
26b39c5158Smillert	$reason = "UNIX domain sockets not implemented on $^O";
27b39c5158Smillert    }
28de8cc8edSafresh1    elsif (! $can_fork) {
29b39c5158Smillert	$reason = 'no fork';
30b39c5158Smillert    }
31de8cc8edSafresh1    elsif ($^O eq 'MSWin32') {
32de8cc8edSafresh1      if ($ENV{CONTINUOUS_INTEGRATION}) {
33de8cc8edSafresh1         $reason = 'Skipping on Windows CI, see gh17575 and gh17429';
34de8cc8edSafresh1      } else {
35de8cc8edSafresh1       $reason = "AF_UNIX unavailable or disabled on this platform"
36de8cc8edSafresh1         unless eval { socket(my $sock, PF_UNIX, SOCK_STREAM, 0) };
37de8cc8edSafresh1      }
38de8cc8edSafresh1    }
39de8cc8edSafresh1
40b39c5158Smillert    if ($reason) {
41b39c5158Smillert	print "1..0 # Skip: $reason\n";
42b39c5158Smillert	exit 0;
43b39c5158Smillert    }
44b39c5158Smillert}
45b39c5158Smillert
46*256a93a4Safresh1my $PATH = "sock-$$";
47b39c5158Smillert
48b39c5158Smillertif ($^O eq 'os2') {	# Can't create sockets with relative path...
49b39c5158Smillert  require Cwd;
50b39c5158Smillert  my $d = Cwd::cwd();
51b39c5158Smillert  $d =~ s/^[a-z]://i;
52b39c5158Smillert  $PATH = "$d/$PATH";
53b39c5158Smillert}
54b39c5158Smillert
55b39c5158Smillert# Test if we can create the file within the tmp directory
565759b3d2Safresh1if (-e $PATH or not open(TEST, '>', $PATH) and $^O ne 'os2') {
57b39c5158Smillert    print "1..0 # Skip: cannot open '$PATH' for write\n";
58b39c5158Smillert    exit 0;
59b39c5158Smillert}
60b39c5158Smillertclose(TEST);
61b39c5158Smillertunlink($PATH) or $^O eq 'os2' or die "Can't unlink $PATH: $!";
62b39c5158Smillert
63b39c5158Smillert# Start testing
64b39c5158Smillert$| = 1;
65b39c5158Smillertprint "1..5\n";
66b39c5158Smillert
67*256a93a4Safresh1my $listen = IO::Socket::UNIX->new(Local => $PATH, Listen => 0);
68b39c5158Smillert
69b39c5158Smillert# Sometimes UNIX filesystems are mounted for security reasons
70b39c5158Smillert# with "nodev" option which spells out "no" for creating UNIX
71b39c5158Smillert# local sockets.  Therefore we will retry with a File::Temp
72b39c5158Smillert# generated filename from a temp directory.
73b39c5158Smillertunless (defined $listen) {
74b39c5158Smillert    eval { require File::Temp };
75b39c5158Smillert    unless ($@) {
76*256a93a4Safresh1	File::Temp->import( 'mktemp' );
77b39c5158Smillert	for my $TMPDIR ($ENV{TMPDIR}, "/tmp") {
78b39c5158Smillert	    if (defined $TMPDIR && -d $TMPDIR && -w $TMPDIR) {
79b39c5158Smillert		$PATH = mktemp("$TMPDIR/sXXXXXXXX");
80b39c5158Smillert		last if $listen = IO::Socket::UNIX->new(Local => $PATH,
81b39c5158Smillert							Listen => 0);
82b39c5158Smillert	    }
83b39c5158Smillert	}
84b39c5158Smillert    }
85b39c5158Smillert    defined $listen or die "$PATH: $!";
86b39c5158Smillert}
87b39c5158Smillertprint "ok 1\n";
88b39c5158Smillert
89*256a93a4Safresh1if (my $pid = fork()) {
90b39c5158Smillert
91*256a93a4Safresh1    my $sock = $listen->accept();
92b39c5158Smillert
93b39c5158Smillert    if (defined $sock) {
94b39c5158Smillert	print "ok 2\n";
95b39c5158Smillert
96b39c5158Smillert	print $sock->getline();
97b39c5158Smillert
98b39c5158Smillert	print $sock "ok 4\n";
99b39c5158Smillert
100b39c5158Smillert	$sock->close;
101b39c5158Smillert
102b39c5158Smillert	waitpid($pid,0);
103b39c5158Smillert	unlink($PATH) || $^O eq 'os2' || warn "Can't unlink $PATH: $!";
104b39c5158Smillert
105b39c5158Smillert	print "ok 5\n";
106b39c5158Smillert    } else {
107b39c5158Smillert	print "# accept() failed: $!\n";
108b39c5158Smillert	for (2..5) {
109b39c5158Smillert	    print "not ok $_ # accept failed\n";
110b39c5158Smillert	}
111b39c5158Smillert    }
112b39c5158Smillert} elsif(defined $pid) {
113b39c5158Smillert
114*256a93a4Safresh1    my $sock = IO::Socket::UNIX->new(Peer => $PATH) or die "$!";
115b39c5158Smillert
116b39c5158Smillert    print $sock "ok 3\n";
117b39c5158Smillert
118b39c5158Smillert    print $sock->getline();
119b39c5158Smillert
120b39c5158Smillert    $sock->close;
121b39c5158Smillert
122b39c5158Smillert    exit;
123b39c5158Smillert} else {
124b39c5158Smillert die;
125b39c5158Smillert}
126