0

I'm doing some practice questions for an exam and one of the questions gives two pieces of code called parent.c and child.c . Parent creates a child and fires signals at it and child displays a message every time it receives a signal. Child will spend rest of it's time printing a message from main. The question is to describe what is wrong with the signal handling in child.c and to re-write the code to correct it. I get the general idea of signals but have a lot of difficulty implementing them. I'm not sure if procmask in child.c is working properly, I'm not completely comfortable with signals but I can't see why you'd put NULL as the last parameter so maybe that's part of why it's wrong? Could someone please point me in the right direction and give me an idea of what part of the code is wrong and why.

Parent.c

#include <unistd.h>
#include <signal.h>
int
main(int argc, char *argv[])
{
    pid_t pid;
    sigset_t set;

    sigemptyset(&set);

    sigaddset(&set, SIGUSR1);

    sigprocmask(SIG_BLOCK, &set, NULL);

    pid = fork();

    if (pid == 0) {
        execlp("./child", "./child", NULL);
    }

    while (1) {
        kill(pid, SIGUSR1);
    }

    return (0);
}

Child.c

#define _XOPEN_SOURCE 500

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

static void
handler(int signo)
{
    printf("This is the SIGUSR1 signal handler!\n");
}

int
main(void)
{
    sigset_t set;

    sigemptyset(&set);

    sigset(SIGUSR1, handler);

    sigprocmask(SIG_SETMASK, &set, NULL);

    while (1) {
        printf("This is main()!\n");
    }

    return (0);
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
user1786327
  • 43
  • 1
  • 4
  • There *is* something wrong with the child's `sigprocmask`. To say any more would give the whole thing away. Can you explain what the child process is trying to do there? If you understand that, then seeing why it's wrong shouldn't be very hard. –  Aug 05 '13 at 16:45

2 Answers2

0
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

The last parameter is used to store the old signal mask. When it's NULL, it means we don't need to store the old signal mask.

Note that you shouldn't use printf in a signal handler, because it's not reentrant, see How to avoid using printf in a signal handler?

And the usage of execlp is wrong, because NULL could be defined as 0, and the compiler may think it's an integer, not a null pointer.

execlp("./child", "./child", NULL);

The last parameter should be (char *)0, like this:

execlp("./child", (char *)0);
Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • Thanks for the comments! Especially for explaining the sigprocmask parameters. The question only wants us to change Child.c not Parent.c so I don't think the lecturer is looking for is to fix the execlp line. – user1786327 Aug 05 '13 at 12:33
0

As man sigset states sigset is obsolete and you should use sigaction. Here is an example on how to use it.

zoska
  • 1,684
  • 11
  • 23