1

I just learning about signals in C, and I want to send a signal from parent to child, but I can't understand why the handler isn't working here...

My code:

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

void handler(int signumber){
  printf("Signal with number %i has arrived\n",signumber);
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  //sigfillset(&sigset); //each signal is in the set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if (child>0)
  {
    printf("I'm parrent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(getppid(),SIGTERM); 
    printf("I sent it.\n");   
  }
  else
  {
    wait(NULL);
    sleep(2);
    printf("I'm the child wainting for signal.\n");

    sigprocmask(SIG_UNBLOCK,&sigset,NULL); 


    int status;
    wait(&status);
    printf("Child process ended\n");
  }
  return 0;
}

And this is the result:

I'm parrent
Waits 2 seconds, then send a SIGTERM 15 signal (it is blocked)
I'm the child wainting for signal.
Child process ended
I sent it.

And one more thing, I know, I have to use sigsuspend(sigset); instead of handler, because the printf isn't safe in handler, but How can I use it in this case?

Gábor
  • 327
  • 1
  • 7
  • Your child is calling `wait`...what process do you think it's waiting for? The parent is sending a signal to its parent....why do you think it will be delivered to the child? – William Pursell Jan 26 '19 at 02:19
  • @WilliamPursell well, I want to send to child from the parent, so as I thought, with `wait` the child can wait for the parent... – Gábor Jan 26 '19 at 12:03
  • @Gábor `wait` in UNIX language means to retrieve process change/termination status. UNIXes only allow parents to retrieve the process change status of their children, not the other way around. – Petr Skocik Jan 26 '19 at 23:24
  • @PSkocik ok, thank's, I think, I got it. – Gábor Jan 27 '19 at 15:41

1 Answers1

0

Wait is mainly for reaping child statuses (generally for observing child status changes). Using it in the child doesn't make much sense. Yes, you can use sigsuspend to wait for the signal. It could look like this:

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


#define WRITE(Str) (void)write(1,Str,strlen(Str))
void handler(int signumber)
{
    WRITE("Signal arrived\n");
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if(0>child) return EXIT_FAILURE;
  if (child>0) {
    int status;
    printf("I'm the parent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(child,SIGTERM);
    printf("I sent it.\n");
  }
  else
  {
    sigemptyset(&sigset); //the child has a different addr-space
                          //so this won't affect the parent
    printf("I'm the child waiting for signal.\n");
    sigsuspend(&sigset);
    printf("Child process ended\n");

  }
  return 0;
}

See the man pages of the individual system functions for more information. You should be checking return codes too, even though most of these particular functions generally don't fail unless you call them wrong (some do, though, e.g., fork() can quite realistically fail if you're out of memory).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • Thank you so much! Am I wrong if I think with `kill(child,SIGTERM);` you direct the parent to the child? – Gábor Jan 26 '19 at 12:05
  • If I have more than one child than how can I chose which one was selected? Can I chose? – Gábor Jan 26 '19 at 12:20
  • @Gábor That's what the first parameter is for. Read the manual. https://linux.die.net/man/2/kill – Petr Skocik Jan 26 '19 at 13:34
  • How can I use signals and pipes at the same time? I tried, they work separately, but if I want to use them in one single program than they, don't want to work. I wrote it here: https://stackoverflow.com/questions/54394374/how-to-use-pipes-and-signals-correctly-at-the-same-time – Gábor Jan 28 '19 at 01:12