skip to Main Content

I’m trying to use the signaling mechanism of UNIX to do some processing. To test out this functionality, I wrote the following code:

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

void handler(int sig)
{
        printf("Received %d signal in %d!n", sig, getpid());
        if(sig == SIGUSR2)
                exit(0);
        signal(sig, handler);
}

int main()
{
        pid_t child = fork();
        if(child == 0)
        {
                // Child process
                while(1)
                {
                        signal(SIGUSR1, handler);
                        signal(SIGUSR2, handler);
                        pause();
                }
        }
        else
        {
                // Parent Process
                for(int i = 0; i < 10; i++)
                {
                        printf("Sending SIGUSR1 signal to %dn", child);
                        kill(child, SIGUSR1);
                        sleep(1);
                }
                printf("Sending SIGTERM signaln");
                kill(child, SIGTERM);
                wait(NULL);
        }
}

I am compiling this code using gcc main.c -o test. When I run this code on my ArchLinux laptop, I get the following output:

Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGUSR1 signal to 212965
Sending SIGTERM signal

As you can see the child process does not print any messages when I run this code on my machine. However, when I run the exact same code on a Ubuntu VM, I get this output:

Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGUSR1 signal to 1153
Received 10 signal in 1153!
Sending SIGTERM signal

My machine is running Linux Kernel v6.11.3 and the VM is running Linux Kernel v6.8.0. Since the signals API is a part of the UNIX standard, the kernel version should not matter. Then why is it that I can’t see any messages from the child process when I run the code on my machine?

To figure out what the issue on my machine is, I re-ran the code multiple times after commenting out various lines one by one. The problem seems to be with the kill syscall. If I comment out the calls to kill, the child process starts printing messages. However, if my code contains calls to kill, the the child process does not print out anything. Why is this happening? What am I doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    I found the issue. The problem was that the parent was sending the signals to the child before the child could register the signal handler in the first place. Since the default behavior when SIGUSR1 and SIGUSR2 is received is to terminate, the child was exiting before it could print anything. Adding a 1 second delay in the parent process fixed the issue.


  2. This may or may not solve your issue, It is recommended to use sigaction() instead of signal(). sigaction() is more consistent and reliable, allowing better control over signal delivery and handling. Generally, from experience, sigaction is a lot more portable, as concured by the GNU Docs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search