views:

111

answers:

2

I'm having trouble with a process forking exercise. I want to fork a child process and have it hang after announcing it has been forked, and wait for a signal to terminate, after which the parent process must announce it is terminating and then exit.

I can get the processes forked and have the parent wait for the hanging child to be killed by the signal, but it seems to kill the parent as well. I tried killing the child process specifically by its PID, but with no success.

Thanks for any help!

Code:

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


void catchInt (int signum)
{
    printf("\nMy  sincerest apologies, master\n");
    /*kill(0, SIGINT);*/
    exit(0);
}

void ignoreInt (int signum)
{
    wait(NULL);
}

int main () {

    pid_t  pid;

    /* fork process */
    pid = fork();
    if (pid < 0) /* error handler */ 
    {      
        fprintf(stderr, "Fork Failed");
        exit(-1);
    }

    else if (pid == 0) /* child */    
    { 
        printf("Child reporting in\n");
        signal(SIGINT, catchInt);
        for ( ;; )
            pause();
    }

    else /* parent */
    {
        /* parent will wait for the child to complete */
        signal(SIGINT, ignoreInt);
        wait(NULL);
        printf("You're welcome\n");
        exit(0);
    }

}
+3  A: 

Even assuming you fix the code so it compiles (you've not defined tempPID), there are problems:

  • You set the child to go to sleep until a signal arrives.
  • You set the parent to wait until the child dies.

So, you have a state where neither process is going to do anything more.

You probably need the parent to send a signal to the child:

kill(pid, SIGINT);
  • It is not clear that you need the parent to set a signal handler.
  • You probably want the child to set a signal handler.
  • You probably don't want the infinite loop in the child.
  • Oh, and void main() is incorrect - int main() or int main(void) or int main(int argc, char **argv) are the approved declarations for main().
  • And it is tidier if you return a value (0) from main(). The C99 standard does permit you to drop off the end of main() and will treat that as returning zero, but only if the function is properly declared as returning an int.
  • The header for wait() and relatives in POSIX is <sys/wait.h>.

And, because I'm a sucker, here's code that compiles and might even do what you want:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>            /* getpid() */ 
#include <stdlib.h>
#include <sys/wait.h>

void catchInt(int signum)
{
    printf("Child's PID is %d\n", (int)getpid());
    printf("My sincerest apologies, master\n");
    exit(1);
}

int main()
{
    pid_t  pid = fork();
    if (pid < 0) /* error handler */ 
    {      
        fprintf(stderr, "Fork Failed");
        exit(-1);
    }
    else if (pid == 0) /* child */    
    { 
        printf("Child reporting in\n");
        signal(SIGINT, catchInt);
        pause();
    }    
    else /* parent */
    {
        sleep(1);
        kill(pid, SIGINT);
        wait(NULL);
        printf("You're welcome\n");
    }
    return(0);
}
Jonathan Leffler
I tidied up the code, tempPID was a leftover scrap of trying out different ways to kill the child. The reason both processes loop infinitely is that they are waiting for the SIGINT signal to be sent by pressing CTRL+C, I should have clarified. Also Johnathan, the code will not compile without sys/types.h to pass the prototype for pid_t.
JKomusin
@Josh: which environment are you running in that still needs an explicit `<sys/types.h>`? I haven't come across a machine like that in a long time - at least five years. But, as I noted in an initial comment, there was once a time when the POSIX standard or [Single UNIX Specification 1997](http://www.opengroup.org/onlinepubs/007908799/xsh/getpid.html) standard required that.
Jonathan Leffler
A: 

Just figured out what I was doing wrong, I should have realized SIGINT is sent to every process, and so the parent was simply being sent an unhandled SIGINT, causing it to exit. Thanks for all the help (my apologies on the sloppy coding, I really shouldn't wait until the program is completed to clean that up), the code's been edited above and works as intended.

Thanks again.

JKomusin