0

I am trying to write a C program in which the parent process suspends the child process and after a few seconds continues executing it.

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

void sigstop(); 
void sigcont();
void sigquit();

int main()
{ 
   int pid; 
   if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }
    if (pid == 0)
     { /* child */
       signal(SIGSTOP,sigstop);
       signal(SIGCONT,sigcont);
       signal(SIGQUIT, sigquit);
       for(;;); /* loop for ever */
     }
     else {
        printf("\nPARENT: sending SIGSTOP to suspend the process\n\n");
        kill(pid, SIGSTOP);
        sleep(5);
        printf("\nPARENT: sending SIGCONT to continue the suspended process\n\n");
        kill(pid, SIGCONT);
        sleep(5);
        printf("killing child");
        kill(pid,SIGQUIT);
        sleep(5);
     }
}

void sigstop()
{  
   printf("CHILD: I've been suspended\n");
}

void sigcont()
{  
   printf("CHILD: I'm back\n");
}

void sigquit()
{ 
    printf("My DADDY has Killed me!!!\n");
    exit(0);
}

printf inside sigstop() never gets executed and sigquit() gets called before printf("killing child");. How does this happen and how can I get output in proper order ?

user7518348
  • 31
  • 1
  • 8
  • `SIGQUIT` does not _kill_ a process. That would be `SIGKILL`. – too honest for this site Feb 09 '17 at 13:09
  • Calling `printf()` in a signal handler invokes undefined behavior. Only async-signal-safe functions can be safely called from within a signal handler: *the behavior is undefined ... if the signal handler calls any function defined in this standard other than one of the functions listed in the following table*. See http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 – Andrew Henle Feb 09 '17 at 13:38

1 Answers1

4

If you read the signal(7) manual page you will see that

The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

You simply can not catch that signal.


The last bit, about "Killing child" get printed in the wrong order is very easy to fix: Add a trailing newline to the string you print.

This is because output to stdout (which is what printf writes to) is by default line-buffered. This means that the internal buffer of stdout is flushed (i.e. actually written to the terminal) on a newline. If you don't have the newline, then the buffer will be flushed when the process exits, which is after you exit the child process.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621