xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/ext/POSIX/t/sigaction.t (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!./perl
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gateBEGIN {
4*0Sstevel@tonic-gate	chdir 't' if -d 't';
5*0Sstevel@tonic-gate	unshift @INC, '../lib';
6*0Sstevel@tonic-gate}
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gateBEGIN{
9*0Sstevel@tonic-gate	# Don't do anything if POSIX is missing, or sigaction missing.
10*0Sstevel@tonic-gate	use Config;
11*0Sstevel@tonic-gate	eval 'use POSIX';
12*0Sstevel@tonic-gate	if($@ || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos' ||
13*0Sstevel@tonic-gate	   $^O eq 'MacOS' || ($^O eq 'VMS' && !$Config{'d_sigaction'})) {
14*0Sstevel@tonic-gate		print "1..0\n";
15*0Sstevel@tonic-gate		exit 0;
16*0Sstevel@tonic-gate	}
17*0Sstevel@tonic-gate}
18*0Sstevel@tonic-gate
19*0Sstevel@tonic-gateuse strict;
20*0Sstevel@tonic-gateuse vars qw/$bad7 $ok10 $bad18 $ok/;
21*0Sstevel@tonic-gate
22*0Sstevel@tonic-gate$^W=1;
23*0Sstevel@tonic-gate
24*0Sstevel@tonic-gateprint "1..25\n";
25*0Sstevel@tonic-gate
26*0Sstevel@tonic-gatesub IGNORE {
27*0Sstevel@tonic-gate	$bad7=1;
28*0Sstevel@tonic-gate}
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gatesub DEFAULT {
31*0Sstevel@tonic-gate	$bad18=1;
32*0Sstevel@tonic-gate}
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gatesub foo {
35*0Sstevel@tonic-gate	$ok=1;
36*0Sstevel@tonic-gate}
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gatemy $newaction=POSIX::SigAction->new('::foo', new POSIX::SigSet(SIGUSR1), 0);
39*0Sstevel@tonic-gatemy $oldaction=POSIX::SigAction->new('::bar', new POSIX::SigSet(), 0);
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate{
42*0Sstevel@tonic-gate	my $bad;
43*0Sstevel@tonic-gate	local($SIG{__WARN__})=sub { $bad=1; };
44*0Sstevel@tonic-gate	sigaction(SIGHUP, $newaction, $oldaction);
45*0Sstevel@tonic-gate	if($bad) { print "not ok 1\n" } else { print "ok 1\n"}
46*0Sstevel@tonic-gate}
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gateif($oldaction->{HANDLER} eq 'DEFAULT' ||
49*0Sstevel@tonic-gate   $oldaction->{HANDLER} eq 'IGNORE')
50*0Sstevel@tonic-gate  { print "ok 2\n" } else { print "not ok 2 # ", $oldaction->{HANDLER}, "\n"}
51*0Sstevel@tonic-gateprint $SIG{HUP} eq '::foo' ? "ok 3\n" : "not ok 3\n";
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gatesigaction(SIGHUP, $newaction, $oldaction);
54*0Sstevel@tonic-gateif($oldaction->{HANDLER} eq '::foo')
55*0Sstevel@tonic-gate  { print "ok 4\n" } else { print "not ok 4\n"}
56*0Sstevel@tonic-gateif($oldaction->{MASK}->ismember(SIGUSR1))
57*0Sstevel@tonic-gate  { print "ok 5\n" } else { print "not ok 5\n"}
58*0Sstevel@tonic-gateif($oldaction->{FLAGS}) {
59*0Sstevel@tonic-gate    if ($^O eq 'linux' || $^O eq 'unicos') {
60*0Sstevel@tonic-gate	print "ok 6 # Skip: sigaction() thinks different in $^O\n";
61*0Sstevel@tonic-gate    } else {
62*0Sstevel@tonic-gate	print "not ok 6\n";
63*0Sstevel@tonic-gate    }
64*0Sstevel@tonic-gate} else {
65*0Sstevel@tonic-gate    print "ok 6\n";
66*0Sstevel@tonic-gate}
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate$newaction=POSIX::SigAction->new('IGNORE');
69*0Sstevel@tonic-gatesigaction(SIGHUP, $newaction);
70*0Sstevel@tonic-gatekill 'HUP', $$;
71*0Sstevel@tonic-gateprint $bad7 ? "not ok 7\n" : "ok 7\n";
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gateprint $SIG{HUP} eq 'IGNORE' ? "ok 8\n" : "not ok 8\n";
74*0Sstevel@tonic-gatesigaction(SIGHUP, POSIX::SigAction->new('DEFAULT'));
75*0Sstevel@tonic-gateprint $SIG{HUP} eq 'DEFAULT' ? "ok 9\n" : "not ok 9\n";
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate$newaction=POSIX::SigAction->new(sub { $ok10=1; });
78*0Sstevel@tonic-gatesigaction(SIGHUP, $newaction);
79*0Sstevel@tonic-gate{
80*0Sstevel@tonic-gate	local($^W)=0;
81*0Sstevel@tonic-gate	kill 'HUP', $$;
82*0Sstevel@tonic-gate}
83*0Sstevel@tonic-gateprint $ok10 ? "ok 10\n" : "not ok 10\n";
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gateprint ref($SIG{HUP}) eq 'CODE' ? "ok 11\n" : "not ok 11\n";
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gatesigaction(SIGHUP, POSIX::SigAction->new('::foo'));
88*0Sstevel@tonic-gate# Make sure the signal mask gets restored after sigaction croak()s.
89*0Sstevel@tonic-gateeval {
90*0Sstevel@tonic-gate	my $act=POSIX::SigAction->new('::foo');
91*0Sstevel@tonic-gate	delete $act->{HANDLER};
92*0Sstevel@tonic-gate	sigaction(SIGINT, $act);
93*0Sstevel@tonic-gate};
94*0Sstevel@tonic-gatekill 'HUP', $$;
95*0Sstevel@tonic-gateprint $ok ? "ok 12\n" : "not ok 12\n";
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gateundef $ok;
98*0Sstevel@tonic-gate# Make sure the signal mask gets restored after sigaction returns early.
99*0Sstevel@tonic-gatemy $x=defined sigaction(SIGKILL, $newaction, $oldaction);
100*0Sstevel@tonic-gatekill 'HUP', $$;
101*0Sstevel@tonic-gateprint !$x && $ok ? "ok 13\n" : "not ok 13\n";
102*0Sstevel@tonic-gate
103*0Sstevel@tonic-gate$SIG{HUP}=sub {};
104*0Sstevel@tonic-gatesigaction(SIGHUP, $newaction, $oldaction);
105*0Sstevel@tonic-gateprint ref($oldaction->{HANDLER}) eq 'CODE' ? "ok 14\n" : "not ok 14\n";
106*0Sstevel@tonic-gate
107*0Sstevel@tonic-gateeval {
108*0Sstevel@tonic-gate	sigaction(SIGHUP, undef, $oldaction);
109*0Sstevel@tonic-gate};
110*0Sstevel@tonic-gateprint $@ ? "not ok 15\n" : "ok 15\n";
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gateeval {
113*0Sstevel@tonic-gate	sigaction(SIGHUP, 0, $oldaction);
114*0Sstevel@tonic-gate};
115*0Sstevel@tonic-gateprint $@ ? "not ok 16\n" : "ok 16\n";
116*0Sstevel@tonic-gate
117*0Sstevel@tonic-gateeval {
118*0Sstevel@tonic-gate	sigaction(SIGHUP, bless({},'Class'), $oldaction);
119*0Sstevel@tonic-gate};
120*0Sstevel@tonic-gateprint $@ ? "ok 17\n" : "not ok 17\n";
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gateif ($^O eq 'VMS') {
123*0Sstevel@tonic-gate    print "ok 18 # Skip: SIGCONT not trappable in $^O\n";
124*0Sstevel@tonic-gate} else {
125*0Sstevel@tonic-gate    $newaction=POSIX::SigAction->new(sub { $ok10=1; });
126*0Sstevel@tonic-gate    if (eval { SIGCONT; 1 }) {
127*0Sstevel@tonic-gate	sigaction(SIGCONT, POSIX::SigAction->new('DEFAULT'));
128*0Sstevel@tonic-gate	{
129*0Sstevel@tonic-gate	    local($^W)=0;
130*0Sstevel@tonic-gate	    kill 'CONT', $$;
131*0Sstevel@tonic-gate	}
132*0Sstevel@tonic-gate    }
133*0Sstevel@tonic-gate    print $bad18 ? "not ok 18\n" : "ok 18\n";
134*0Sstevel@tonic-gate}
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gate{
137*0Sstevel@tonic-gate    local $SIG{__WARN__} = sub { }; # Just suffer silently.
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate    my $hup20;
140*0Sstevel@tonic-gate    my $hup21;
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate    sub hup20 { $hup20++ }
143*0Sstevel@tonic-gate    sub hup21 { $hup21++ }
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate    sigaction("FOOBAR", $newaction);
146*0Sstevel@tonic-gate    print "ok 19\n"; # no coredump, still alive
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gate    $newaction = POSIX::SigAction->new("hup20");
149*0Sstevel@tonic-gate    sigaction("SIGHUP", $newaction);
150*0Sstevel@tonic-gate    kill "HUP", $$;
151*0Sstevel@tonic-gate    print $hup20 == 1 ? "ok 20\n" : "not ok 20\n";
152*0Sstevel@tonic-gate
153*0Sstevel@tonic-gate    $newaction = POSIX::SigAction->new("hup21");
154*0Sstevel@tonic-gate    sigaction("HUP", $newaction);
155*0Sstevel@tonic-gate    kill "HUP", $$;
156*0Sstevel@tonic-gate    print $hup21 == 1 ? "ok 21\n" : "not ok 21\n";
157*0Sstevel@tonic-gate}
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate# "safe" attribute.
160*0Sstevel@tonic-gate# for this one, use the accessor instead of the attribute
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate# standard signal handling via %SIG is safe
163*0Sstevel@tonic-gate$SIG{HUP} = \&foo;
164*0Sstevel@tonic-gate$oldaction = POSIX::SigAction->new;
165*0Sstevel@tonic-gatesigaction(SIGHUP, undef, $oldaction);
166*0Sstevel@tonic-gateprint $oldaction->safe ? "ok 22\n" : "not ok 22\n";
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate# SigAction handling is not safe ...
169*0Sstevel@tonic-gatesigaction(SIGHUP, POSIX::SigAction->new(\&foo));
170*0Sstevel@tonic-gatesigaction(SIGHUP, undef, $oldaction);
171*0Sstevel@tonic-gateprint $oldaction->safe ? "not ok 23\n" : "ok 23\n";
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate# ... unless we say so!
174*0Sstevel@tonic-gate$newaction = POSIX::SigAction->new(\&foo);
175*0Sstevel@tonic-gate$newaction->safe(1);
176*0Sstevel@tonic-gatesigaction(SIGHUP, $newaction);
177*0Sstevel@tonic-gatesigaction(SIGHUP, undef, $oldaction);
178*0Sstevel@tonic-gateprint $oldaction->safe ? "ok 24\n" : "not ok 24\n";
179*0Sstevel@tonic-gate
180*0Sstevel@tonic-gate# And safe signal delivery must work
181*0Sstevel@tonic-gate$ok = 0;
182*0Sstevel@tonic-gatekill 'HUP', $$;
183*0Sstevel@tonic-gateprint $ok ? "ok 25\n" : "not ok 25\n";
184