xref: /openbsd-src/gnu/usr.bin/perl/t/io/sem.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
16fb12b70Safresh1#!perl
26fb12b70Safresh1
36fb12b70Safresh1BEGIN {
46fb12b70Safresh1  chdir 't' if -d 't';
56fb12b70Safresh1
66fb12b70Safresh1  require "./test.pl";
75759b3d2Safresh1  set_up_inc( '../lib' ) if -d '../lib' && -d '../ext';
8*5486feefSafresh1  require Config; Config->import;
96fb12b70Safresh1
106fb12b70Safresh1  if ($ENV{'PERL_CORE'} && $Config{'extensions'} !~ m[\bIPC/SysV\b]) {
116fb12b70Safresh1    skip_all('-- IPC::SysV was not built');
126fb12b70Safresh1  }
136fb12b70Safresh1  skip_all_if_miniperl();
146fb12b70Safresh1  if ($Config{'d_sem'} ne 'define') {
156fb12b70Safresh1    skip_all('-- $Config{d_sem} undefined');
166fb12b70Safresh1  }
176fb12b70Safresh1}
186fb12b70Safresh1
196fb12b70Safresh1use strict;
20256a93a4Safresh1use warnings;
216fb12b70Safresh1our $TODO;
226fb12b70Safresh1
236fb12b70Safresh1use sigtrap qw/die normal-signals error-signals/;
24256a93a4Safresh1use IPC::SysV qw/ IPC_PRIVATE S_IRUSR S_IWUSR IPC_RMID SETVAL GETVAL SETALL GETALL IPC_CREAT IPC_STAT /;
256fb12b70Safresh1
266fb12b70Safresh1my $id;
276fb12b70Safresh1my $nsem = 10;
28256a93a4Safresh1my $ignored = 0;
296fb12b70Safresh1END { semctl $id, 0, IPC_RMID, 0 if defined $id }
306fb12b70Safresh1
316fb12b70Safresh1{
326fb12b70Safresh1    local $SIG{SYS} = sub { skip_all("SIGSYS caught") } if exists $SIG{SYS};
336fb12b70Safresh1    $id = semget IPC_PRIVATE, $nsem, S_IRUSR | S_IWUSR | IPC_CREAT;
346fb12b70Safresh1}
356fb12b70Safresh1
366fb12b70Safresh1if (not defined $id) {
376fb12b70Safresh1    my $info = "semget failed: $!";
386fb12b70Safresh1    if ($! == &IPC::SysV::ENOSPC || $! == &IPC::SysV::ENOSYS ||
396fb12b70Safresh1	$! == &IPC::SysV::ENOMEM || $! == &IPC::SysV::EACCES) {
406fb12b70Safresh1        skip_all($info);
416fb12b70Safresh1    }
426fb12b70Safresh1    else {
436fb12b70Safresh1        die $info;
446fb12b70Safresh1    }
456fb12b70Safresh1}
466fb12b70Safresh1else {
47256a93a4Safresh1    plan(tests => 22);
486fb12b70Safresh1    pass('acquired semaphore');
496fb12b70Safresh1}
506fb12b70Safresh1
51256a93a4Safresh1my @warnings;
52256a93a4Safresh1$SIG{__WARN__} = sub { push @warnings, "@_"; print STDERR @_; };
536fb12b70Safresh1{ # [perl #120635] 64 bit big-endian semctl SETVAL bug
54256a93a4Safresh1    ok(semctl($id, $ignored, SETALL, pack("s!*",(0)x$nsem)),
556fb12b70Safresh1       "Initialize all $nsem semaphores to zero");
566fb12b70Safresh1
576fb12b70Safresh1    my $sem2set = 3;
58256a93a4Safresh1    my $semval = 192;
596fb12b70Safresh1    ok(semctl($id, $sem2set, SETVAL, $semval),
606fb12b70Safresh1       "Set semaphore $sem2set to $semval");
616fb12b70Safresh1
626fb12b70Safresh1    my $semvals;
63256a93a4Safresh1    ok(semctl($id, $ignored, GETALL, $semvals),
646fb12b70Safresh1       'Get current semaphore values');
656fb12b70Safresh1
666fb12b70Safresh1    my @semvals = unpack("s!*", $semvals);
676fb12b70Safresh1    is(scalar(@semvals), $nsem,
686fb12b70Safresh1       "Make sure we get back statuses for all $nsem semaphores");
696fb12b70Safresh1
706fb12b70Safresh1    is($semvals[$sem2set], $semval,
716fb12b70Safresh1       "Checking value of semaphore $sem2set");
726fb12b70Safresh1
73256a93a4Safresh1    is(semctl($id, $sem2set, GETVAL, $ignored), $semval,
746fb12b70Safresh1       "Check value via GETVAL");
75256a93a4Safresh1
76256a93a4Safresh1    # check utf-8 flag handling
77256a93a4Safresh1    # first that we reset it on a fetch
78256a93a4Safresh1    utf8::upgrade($semvals);
79256a93a4Safresh1    ok(semctl($id, $ignored, GETALL, $semvals),
80256a93a4Safresh1       "fetch into an already UTF-8 buffer");
81256a93a4Safresh1    @semvals = unpack("s!*", $semvals);
82256a93a4Safresh1    is($semvals[$sem2set], $semval,
83256a93a4Safresh1       "Checking value of semaphore $sem2set after fetch into originally UTF-8 buffer");
84256a93a4Safresh1
85256a93a4Safresh1    # second that we treat it as bytes on input
86256a93a4Safresh1    @semvals = ( 0 ) x $nsem;
87256a93a4Safresh1    $semvals[$sem2set] = $semval + 1;
88256a93a4Safresh1    $semvals = pack "s!*", @semvals;
89256a93a4Safresh1    utf8::upgrade($semvals);
90256a93a4Safresh1    # eval{} since it would crash due to the UTF-8 form being longer
91256a93a4Safresh1    ok(eval { semctl($id, $ignored, SETALL, $semvals) },
92256a93a4Safresh1       "set all semaphores from an upgraded string");
93256a93a4Safresh1    # undef here to test it doesn't warn
94256a93a4Safresh1    is(semctl($id, $sem2set, GETVAL, undef), $semval+1,
95256a93a4Safresh1       "test value set from UTF-8");
96256a93a4Safresh1
97256a93a4Safresh1    # third, that we throw on a code point above 0xFF
98256a93a4Safresh1    substr($semvals, 0, 1) = chr(0x101);
99256a93a4Safresh1    ok(!eval { semctl($id, $ignored, SETALL, $semvals); 1 },
100256a93a4Safresh1       "throws on code points above 0xff");
101256a93a4Safresh1    like($@, qr/Wide character/, "with the expected error");
102256a93a4Safresh1
103256a93a4Safresh1    {
104256a93a4Safresh1        # semop tests
105256a93a4Safresh1        ok(semctl($id, $sem2set, SETVAL, 0),
106256a93a4Safresh1           "reset our working entry");
107256a93a4Safresh1        # sanity check without UTF-8
108256a93a4Safresh1        my $op = pack "s!*", $sem2set, $semval, 0;
109256a93a4Safresh1        ok(semop($id, $op), "add to entry $sem2set");
110256a93a4Safresh1        is(semctl($id, $sem2set, GETVAL, 0), $semval,
111256a93a4Safresh1           "check it added to the entry");
112256a93a4Safresh1        utf8::upgrade($op);
113256a93a4Safresh1        # unlike semctl this doesn't throw on a bad size, so we don't need an
114256a93a4Safresh1        # eval with the buggy code
115256a93a4Safresh1        ok(semop($id, $op), "add more to entry $sem2set (UTF-8)");
116256a93a4Safresh1        is(semctl($id, $sem2set, GETVAL, 0), $semval*2,
117256a93a4Safresh1           "check it added to the entry");
118256a93a4Safresh1
119256a93a4Safresh1        substr($op, 0, 1) = chr(0x101);
120256a93a4Safresh1        ok(!eval { semop($id, $op); 1 },
121256a93a4Safresh1           "test semop throws if the op string isn't 'bytes'");
122256a93a4Safresh1        like($@, qr/Wide character/, "with the expected error");
123256a93a4Safresh1    }
1246fb12b70Safresh1}
1256fb12b70Safresh1
126256a93a4Safresh1{
127256a93a4Safresh1    my $stat;
128256a93a4Safresh1    # shouldn't warn
129256a93a4Safresh1    semctl($id, $ignored, IPC_STAT, $stat);
130256a93a4Safresh1    ok(defined $stat, "it statted");
131256a93a4Safresh1}
132256a93a4Safresh1
133256a93a4Safresh1is(scalar @warnings, 0, "no warnings");
134