xref: /openbsd-src/gnu/usr.bin/perl/t/io/msg.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1256a93a4Safresh1#!perl
2256a93a4Safresh1
3256a93a4Safresh1BEGIN {
4256a93a4Safresh1  chdir 't' if -d 't';
5256a93a4Safresh1
6256a93a4Safresh1  require "./test.pl";
7256a93a4Safresh1  set_up_inc( '../lib' ) if -d '../lib' && -d '../ext';
8*5486feefSafresh1  require Config; Config->import;
9256a93a4Safresh1
10256a93a4Safresh1  if ($ENV{'PERL_CORE'} && $Config{'extensions'} !~ m[\bIPC/SysV\b]) {
11256a93a4Safresh1    skip_all('-- IPC::SysV was not built');
12256a93a4Safresh1  }
13256a93a4Safresh1  skip_all_if_miniperl();
14256a93a4Safresh1  if ($Config{'d_msg'} ne 'define') {
15256a93a4Safresh1    skip_all('-- $Config{d_msg} undefined');
16256a93a4Safresh1  }
17256a93a4Safresh1}
18256a93a4Safresh1
19256a93a4Safresh1use strict;
20256a93a4Safresh1use warnings;
21256a93a4Safresh1our $TODO;
22256a93a4Safresh1
23256a93a4Safresh1use sigtrap qw/die normal-signals error-signals/;
24256a93a4Safresh1use IPC::SysV qw/ IPC_PRIVATE S_IRUSR S_IWUSR IPC_RMID IPC_CREAT IPC_STAT IPC_CREAT IPC_NOWAIT/;
25*5486feefSafresh1use Errno qw(EINVAL);
26256a93a4Safresh1
27256a93a4Safresh1my $id;
28256a93a4Safresh1END { msgctl $id, IPC_RMID, 0 if defined $id }
29256a93a4Safresh1
30256a93a4Safresh1{
31256a93a4Safresh1    local $SIG{SYS} = sub { skip_all("SIGSYS caught") } if exists $SIG{SYS};
32256a93a4Safresh1    $id = msgget IPC_PRIVATE, S_IRUSR | S_IWUSR | IPC_CREAT;
33256a93a4Safresh1}
34256a93a4Safresh1
35256a93a4Safresh1if (not defined $id) {
36256a93a4Safresh1    my $info = "msgget failed: $!";
37256a93a4Safresh1    if ($! == &IPC::SysV::ENOSPC || $! == &IPC::SysV::ENOSYS ||
38256a93a4Safresh1	$! == &IPC::SysV::ENOMEM || $! == &IPC::SysV::EACCES) {
39256a93a4Safresh1        skip_all($info);
40256a93a4Safresh1    }
41256a93a4Safresh1    else {
42256a93a4Safresh1        die $info;
43256a93a4Safresh1    }
44256a93a4Safresh1}
45256a93a4Safresh1else {
46256a93a4Safresh1    pass('acquired msg queue');
47256a93a4Safresh1}
48256a93a4Safresh1
49256a93a4Safresh1{
50256a93a4Safresh1    # basic send/receive
51256a93a4Safresh1    my $type = 0x1F0;
52256a93a4Safresh1    my $content = "AB\xFF\xC0";
53256a93a4Safresh1
54256a93a4Safresh1    my $msg = pack("l! a*", $type, $content);
55256a93a4Safresh1    if (ok(msgsnd($id, $msg, IPC_NOWAIT), "send a message")) {
56256a93a4Safresh1        my $rcvbuf;
57256a93a4Safresh1        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it");
58256a93a4Safresh1        is($rcvbuf, $msg, "received should match sent");
59256a93a4Safresh1    }
60256a93a4Safresh1
61256a93a4Safresh1    # try upgraded send
62256a93a4Safresh1    utf8::upgrade(my $umsg = $msg);
63256a93a4Safresh1    if (ok(msgsnd($id, $umsg, IPC_NOWAIT), "send a message (upgraded)")) {
64256a93a4Safresh1        my $rcvbuf;
65256a93a4Safresh1        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it");
66256a93a4Safresh1        is($rcvbuf, $msg, "received should match sent");
67256a93a4Safresh1    }
68256a93a4Safresh1
69256a93a4Safresh1    # try a receive buffer that starts upgraded
70256a93a4Safresh1    if (ok(msgsnd($id, $msg, IPC_NOWAIT), "send a message (upgraded receiver)")) {
71256a93a4Safresh1        my $rcvbuf = "\x{101}";
72256a93a4Safresh1        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it (upgraded receiver)");
73256a93a4Safresh1        is($rcvbuf, $msg, "received should match sent (upgraded receiver)");
74256a93a4Safresh1    }
75256a93a4Safresh1}
76256a93a4Safresh1
77*5486feefSafresh1{
78*5486feefSafresh1    # receive to magic
79*5486feefSafresh1    my $x;
80*5486feefSafresh1    my $fetch = 0;
81*5486feefSafresh1    my $store = 0;
82*5486feefSafresh1    package MyScalar {
83*5486feefSafresh1        sub TIESCALAR { bless {}, shift }
84*5486feefSafresh1        sub FETCH { ++$fetch; $x }
85*5486feefSafresh1        sub STORE { ++$store; $x = $_[1]; }
86*5486feefSafresh1    };
87*5486feefSafresh1    tie my $rcvbuf, "MyScalar";
88*5486feefSafresh1    my $msg = pack("l! a*", 1, "Hello");
89*5486feefSafresh1    my $warn = "";
90*5486feefSafresh1    if (ok(msgsnd($id, $msg, IPC_NOWAIT), "send to magic receive")) {
91*5486feefSafresh1        {
92*5486feefSafresh1            local $SIG{__WARN__} = sub { $warn .= "@_\n" };
93*5486feefSafresh1            ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it (magic receiver)");
94*5486feefSafresh1        }
95*5486feefSafresh1        is($x, $msg, "magic properly triggered");
96*5486feefSafresh1        is($fetch, 0, "should be no fetch");
97*5486feefSafresh1        is($store, 1, "should be one store");
98*5486feefSafresh1        unlike($warn, qr/uninitialized/, "shouldn't be uninitialized warning");
99*5486feefSafresh1    }
100*5486feefSafresh1}
101*5486feefSafresh1
102*5486feefSafresh1{
103*5486feefSafresh1    # this resulted in a panic
104*5486feefSafresh1    my $buf;
105*5486feefSafresh1    ok(!msgrcv($id, $buf, -10, 0, IPC_NOWAIT), "fail with negative length");
106*5486feefSafresh1    is(0+$!, &Errno::EINVAL, "check proper error");
107*5486feefSafresh1}
108*5486feefSafresh1
109256a93a4Safresh1done_testing();
110