Debabrata Bardhan
Debabrata Bardhan

Reputation: 47

Can't ignore signal CHLD, forcing to default

 #include <sys/types.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <iostream>
 #include <unistd.h>
 int main(){


        signal(SIGCHLD,SIG_IGN );
        pid_t pid  = vfork();
        if(pid <0){
            std::cout<< "Error: Fork failed at main!!!";
            exit(1);
        }else if (0 == pid){


            char * cmd[] ={(char*)"../work/C++11/Prj_LargeFile/script/Logger.pl",NULL};
            //char * cmd[] = {(char*)"pwd",NULL};
            //char * cmd[] = {(char*)"/usr/bin/perl",(char*)"../work/C++11/Prj_LargeFile/script/Logger.pl",NULL};

            execvp(cmd[0],cmd);


             _exit(0);
        }
}

I want to have orphan child process which will run a perl script in the backgroud and I want the parent process to be completed without waiting on its child. Hence I have used signal(SIGCHLD,SIG_IGN ) at the beginning to ignore child signal on completion and to avoid zombies. But when i am running the code its giving me error as Can't ignore signal CHLD, forcing to default. . On the other when i am running those commented lines instead its running with the desired signal. what is the reason of that?

Upvotes: 0

Views: 1379

Answers (1)

Ben Stern
Ben Stern

Reputation: 295

Perl is issuing this warning. It looks like recent versions of glibc (or possibly particular options in the Linux kernel) have removed the ability to ignore SIGCHLD, as far as Perl is concerned. I don't know why this is the case, but I just ran into it on a system that previously was happy to ignore SIGCHLD.

According to perldoc perlipc, which you should definitely look at for more information, the best thing to address this is:

use POSIX ":sys_wait_h"; # for nonblocking read
$SIG{CHLD} = sub {
    while ((my $child = waitpid(-1, WNOHANG)) > 0) {
        # $Kid_Status{$child} = $?;
    }
};
# do something that forks...

The line with $Kid_Status is from the original perldoc, but I commented it out because the intent is to ignore the child processes, and I wanted to make clear that the inside of the while doesn't need to contain any code. There are a variety of ways to address handling child processes in the perldoc, such as if your Perl script is intended to daemonize or if you intend to exec or die within the handler.

If you can't edit the Perl script you're calling, then I recommend printing a line to STDERR right before the execvp telling the user to ignore the spurious warning. For example,

fputs("The next line is a harmless warning.\n", stderr);

Upvotes: 2

Related Questions