daveg
daveg

Reputation: 1211

How does prctl, set_pdeathsig work in perl?

perl-5.24.0 on RH7

I'd like a forked process to kill itself when it determines that it's parent dies. I've read that I can use Linux::Prctl, set_pdeathsig() to do that. But my test of this doesn't seem to work.

#!/usr/bin/env perl

use strict;

my $pid = fork();
  die if not defined $pid;

if($pid == 0) {
    do_forked_steps();
}

print "====PARENT===\n";
print "Hit <CR> to kill parent.\n";
my $nocare = <>;

exit;

sub do_forked_steps {
    system("/home/dgauthie/PERL/sub_fork.pl");
}

And sub_fork.pl is simply...

#!/usr/bin/env perl

use strict;
use Linux::Prctl;

Linux::Prctl::set_pdeathsig(1);

sleep(300);

exit;

(I believe sending "1" tp set_pdeathsig = SIGHUP. But I also tried "9". Same results)

When I run the first script, I can see both procs using ps in another window. When I hit in the script to kill it, I can see that proc go away, but the second one, the forked process, remains.

What am I doing wrong?

Upvotes: 4

Views: 315

Answers (1)

hobbs
hobbs

Reputation: 240473

You have three processes, not two, because system forks. They are:

  1. The parent process in the parent script ($pid != 0) which waits on <> and calls exit.
  2. The child process, created by fork in the parent script, which calls system. system forks and then waits for its child to exit before returning.
  3. The child process created by system which execs your child script, calls prctl, and sleeps.

When you press enter, process #1 dies, but process #2 does not, and since process #2 is the parent of process #3, the PDEATHSIG is never invoked.

Changing system to exec in your first script, so that a third process isn't created, causes the PDEATHSIG to fire in your toy problem, but without more information it isn't clear if that's suitable in the "real world" version of what you're trying to do.

Upvotes: 4

Related Questions