File: sigtest.pl

package info (click to toggle)
libnet-server-perl 0.87-3sarge1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 400 kB
  • ctags: 215
  • sloc: perl: 2,787; sh: 347; makefile: 46
file content (128 lines) | stat: -rw-r--r-- 2,663 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/perl -w

use IO::Select ();
use IO::Socket ();
use Net::Server::SIG qw(register_sig check_sigs);
use POSIX ();

print "Usage: $0 SIGNAME SAFE|UNSAFE
  (SIGNAME is a standard signal - default is USR1)
  (SAFE will use Net::Server::SIG, UNSAFE uses \$SIG{} - default is SAFE)
  If the child isn't saying anything, the test is invalid.
  If the child dies, look for a core file.
";

my $SIG = shift() || 'USR1';
my $safe = shift() || 'SAFE';
$safe = uc($safe) eq 'UNSAFE' ? undef : 1;
my $x = 0;
my %hash = ();

### set up a pipe
pipe(READ,WRITE);
READ->autoflush(1);
WRITE->autoflush(1);
STDOUT->autoflush(1);

my $pid = fork();
die "Couldn't fork [$!]" unless defined $pid;

### see if child left
$SIG{CHLD} = sub {
  print "P ($$): Child died (\$?=$?)\n"
    while (waitpid(-1, POSIX::WNOHANG()) > 0);
};

### let the parent try to kill the child
if( $pid ){

  sleep(2);

  ### for off children to help bombard the child
  for(1..4){
    my $pid2 = fork();
    unless( defined $pid2 ){
      kill 9, $pid;
      die "Couldn't fork [$!]";
    }
    unless( $pid2 ){
      $SIG{CHLD} = 'DEFAULT';
      last;
    }
  }    

  print "P ($$): Starting up!\n";

  ### kill the child with that signal
  my $n = 50000;
  while (1){
    last unless kill $SIG, $pid;
    unless( ++$x % $n ){
      print "P ($$): $x SIG_$SIG\'s sent.\n";
      print WRITE "$n\n";
    }
  }


### let the child try to stay alive
}else{

  print "C ($$): Starting up!\n";

  my $select = IO::Select->new();
  $select->add(\*READ);

  ### do some variable manipulation in the signal handler
  my $subroutine = sub {
    $hash{foo} = "abcde"x10000;
    $hash{bar} ++;
    delete $hash{baz};
    delete $hash{bar};
  };

  ### register a signal and see if it will bounce off of the can_read
  if( $safe ){
    print "C ($$): Using SAFE signal handler.\n";
    register_sig($SIG => $subroutine);

  ### This is an unsafe signal handler. See how long
  ### it can take signals.
  }else{
    print "C ($$): Using UNSAFE signal handler.\n";
    $SIG{$SIG} = $subroutine;

  }

  my $total = 0;

  ### loop forever trying to stay alive
  while ( 1 ){

    my @fh = $select->can_read(10);

    my $key;
    my $val;

    ### this is the handler for safe (fine under unsafe also)
    next if &check_sigs() && ! @fh;

    ### do some hash manipulation
    delete $hash{foo};
    $hash{bar} = 0;
    $hash{baz} = "abcde"x100000;


    next unless @fh;
    my $line = <READ>;
    chomp($line);
    $total += $line;
    print "C ($$): P said \"$line\"\n";
    
    unless( ++$x % 5 ){
      print "C ($$): $x lines read. $total SIG's received\n";
    }
  }

  print "Child is done\n";
}