0

The parent process forks two children, each replace SIGUSR1 and SIGUSR2 signal respectively.

The parent process replace SIGINT signal, on catching it, send SIGUSR1 and SIGUSR2 to its children respectively.

The expected output when Ctrl-C is pressed should be:

Ctrl+C is pressed。
received SIGUSR1 signal
received SIGUSR2 signal

But on Ctrl-C I've got

Ctrl+C is pressed。

I have no idea why sig_handler_1 and sig_handler_2 are not excuted.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
void fun_ctrl_c(int);
void sig_handler_1(int);
void sig_handler_2(int);
pid_t pid1;
pid_t pid2;
int status;

int main() {
    pid1 = fork();
    if (pid1 == 0) {    // child 1
        // avoid to be killed
        (void) signal(SIGINT, SIG_IGN);
        // replace SIGUSR1
        (void) signal(SIGUSR1, sig_handler_1);
        raise(SIGSTOP);
    } else {
        pid2 = fork();
        if (pid2 == 0) {    // child 2
            // avoid to be killed
            (void) signal(SIGINT, SIG_IGN);
            // replace SIGUSR2
            (void) signal(SIGUSR2, sig_handler_2);
            raise(SIGSTOP);
        } else {    // parent
            (void) signal(SIGINT, fun_ctrl_c);
            waitpid(-1, &status, 0);
        }
    }
    return 0;
}

void fun_ctrl_c(int)
{
    printf("Ctrl+C is pressed。\n");
    kill(pid1 ,SIGUSR1);
    kill(pid2 ,SIGUSR2);
    (void) signal(SIGINT, SIG_DFL);
}

void sig_handler_1(int)
{
    printf("received SIGUSR1 signal\n");
}

void sig_handler_2(int)
{
    printf("received SIGUSR2 signal\n");
}
Zizheng Wu
  • 646
  • 1
  • 12
  • 21
  • 1
    Using 'replace' is not the usual terminology. You seem to be 'handling' the signals, or 'replacing the current signal handlers with different ones'. – Jonathan Leffler Sep 06 '14 at 19:37

1 Answers1

1

Your problem is that you do raise(SIGSTOP); in the child processes, so they're stopped and cannot respond to signals at all.

Replace that with pause(); — the code then works.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

void fun_ctrl_c(int);
void sig_handler_1(int);
void sig_handler_2(int);

pid_t pid1;
pid_t pid2;

int main(void)
{
    pid1 = fork();
    if (pid1 == 0)
    {
        (void) signal(SIGINT, SIG_IGN);
        (void) signal(SIGUSR1, sig_handler_1);
        pause();
        printf("PID %d exiting\n", (int)getpid());
    }
    else if ((pid2 = fork()) == 0)
        {
            (void) signal(SIGINT, SIG_IGN);
            (void) signal(SIGUSR2, sig_handler_2);
            pause();
            printf("PID %d exiting\n", (int)getpid());
        }
        else
        {
            (void) signal(SIGINT, fun_ctrl_c);
            int status;
            int pid;
            printf("Interrupt me!\n");
            while ((pid = waitpid(-1, &status, 0)) != -1)
                printf("Child %d exited with status 0x%.4X\n", pid, status);
            printf("Parent %d exiting\n", (int)getpid());
        }
    return 0;
}

void fun_ctrl_c(int signum)
{
    printf("Ctrl+C is pressed。Received SIGINT (%d) signal\n", signum);
    kill(pid1, SIGUSR1);
    kill(pid2, SIGUSR2);
    (void) signal(SIGINT, SIG_DFL);
}

void sig_handler_1(int signum)
{
    printf("received SIGUSR1 (%d) signal\n", signum);
}

void sig_handler_2(int signum)
{
    printf("received SIGUSR2 (%d) signal\n", signum);
}

Sample run (I called the program sigintusr12):

$ ./sigintusr12
Interrupt me!
^CCtrl+C is pressed。Received SIGINT (2) signal
received SIGUSR2 (31) signal
received SIGUSR1 (30) signal
PID 31184 exiting
PID 31183 exiting
Child 31184 exited with status 0x0000
Child 31183 exited with status 0x0000
Parent 31182 exiting
$

Note that you're not strictly supposed to use printf() (and many other functions, especially those that might need to allocate memory) inside a signal handler. It'll work OK here, but it is not good practice. See How to avoid using printf() in a signal handler? for more information.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278