Home Ask Login Register

Developers Planet

Your answer is one click away!

Simone Bonato February 2016

Get if a signal is received

How can I get if a process receives a signal? The purpose of the following example is to fork a process, read a character with the child process and send SIGUSR1 to parent, but if after 10 seconds the user still have to insert the character, the child process is terminated. The question is how to know if SIGUSR1 is received:

#define _POSIX_SOURCE

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

void handle_USR1()
{
    return;
}

int main(void)
{
    int p[2];
    pid_t pid;

    if(pipe(p) == -1)
    {
        perror("pipe");
        return -1;
    }

    if((pid = fork()) == -1)
    {
        perror("fork");
        return -1;
    }

    if(pid == 0)
    {
        close(p[0]);
        char ch, b;

        ch = getchar();

        if(ch != '\n')
            while((b = getchar()) != '\n' && b != EOF);

        write(p[1], &ch, 1);
        kill(getppid(),SIGUSR1);

        exit(-1);
    }
    else
    {
        signal(SIGUSR1,handle_USR1);
        close(p[1]);
        char ch;

        sleep(10);
        kill(pid, SIGTERM);

        read(p[0],&ch,1);

        //if(/*SIGUSR1 is not recived*/)
        //{
        //    exit(-1);
        //}

        printf("\n\n%c",ch);
    }

    return 0;
}

What can I replace /*SIGUSR1 is not recived*/ with?

Answers


dlmeetei February 2016

Please chek man 2 signal which gives following synopsis

#include <signal.h>

   typedef void (*sighandler_t)(int);

   sighandler_t signal(int signum, sighandler_t handler);

You use signal to register your handler, the handler is of type

 void handler(int signum) {
     //do whatever you like
 }

Here the param sugnum receives the signal number. In your case it SIGUSR1 and can be inside the handle to determine which signal it is


Jonathan Leffler February 2016

In a comment, I suggested:

Your handle_USR1() function should set a static volatile sig_atomic_t variable to a known value (e.g. 1). You can then check that variable to know whether a signal has been received. In Standard C, there's very little else that you can do in a signal handler in a strictly conforming way; in POSIX, you may do considerably more (but be careful: Avoid using printf() in a signal handler may help you).

Here's what I meant translated into code, closely based on your code:

sigusr1.c

#define _POSIX_SOURCE

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

static volatile sig_atomic_t sig = 0;

static void handle_USR1(int signum)
{
    sig = signum;
}

int main(void)
{
    int p[2];
    pid_t pid;

    signal(SIGUSR1, handle_USR1);

    if (pipe(p) == -1)
    {
        perror("pipe");
        return -1;
    }

    if ((pid = fork()) == -1)
    {
        perror("fork");
        return -1;
    }

    if (pid == 0)
    {
        close(p[0]);
        char ch, b;

        ch = getchar();

        if (ch != '\n')
            while ((b = getchar()) != '\n' && b != EOF)
                ;

        write(p[1], &ch, 1);
        kill(getppid(), SIGUSR1);

        exit(-1);
    }
    else
    {
        close(p[1]);
        char ch;

        sleep(10);
        if (sig != 0)
            printf("Signal number %d received while sleeping\n", sig);
        else
        {
            printf("Sending SIGTERM to child %d\n", (int)pid);
            kill(pid, SIGTERM);
        }

        if (read(p[0], &ch, 1) == 1)
            printf("Character sent by child: [%c]\n", ch);
      

Post Status

Asked in February 2016
Viewed 1,896 times
Voted 5
Answered 2 times

Search




Leave an answer


Quote of the day: live life