Gist of the Day: Process Control with fork(), exec(), and kill()

I feel really bad for leaving you all high and dry yesterday… really bad… okay, you’re right, I don’t really feel all that bad.
I have a doosey for you all today though, no doubt about it! One of the most common trends in computers these days is multi-processing. Multiple cores means one program can do more work by spawning extra threads or child processes. I’ve already done a bit of stuff with threading, so here’s a bunch of stuff with forking (tee-hee).

What to Demo?

What am I wanting to demo here?

  1. How to use fork() to spawn a child process.
  2. How to use exec() to load a new script into that child process.
  3. How to detect when that child process is done.
  4. How to send signals to the child process.
  5. A short list of available signals, and which ones you can’t touch

Here’s the flow of the test program:

  1. For each signal in the list
    1. fork() a child process
    2. exec() the watch_perl_die.pl script
    3. Bind to the SIGCHLD signal to a signal handler made on the fly
    4. Send the signal from the list  to the child process using  kill()
    5. Verify that the child did or didn’t drop its head.dat file when it received the signal
    6. Clean up and start again
  2. Verify that we tested all of the signals in the list

The Code

Here’s the top-level script which does the control:

Here’s the child process’ script:

Signals Tried

We tried several different signals, most of which we were able to trap. Two of the signals were, SIGSTOP and SIGKILL, were not able to be trapped. This is a normal part of how signals work. Here’s a link to man 7 signal.

  • SIGINT – Usable, we were able to trap it
  • SIGUSR1 – Usable, we were able to trap it
  • SIGALRM – Usable, we were able to trap it
  • SIGTERM – Usable, we were able to trap it
  • SIGSEGV – Usable, we were able to trap it
  • SIGABRT – Usable, we were able to trap it
  • SIGPIPE – Usable, we were able to trap it
  • SIGCHLD – Usable, we were able to trap it
  • SIGKILL – Unusable, we were not able to trap it
  • SIGSTOP – Unusable, we were not able to trap it

Notes on Process Control

You’ll notice how after I perform the slaughter (kill()) I do two things to verify that this was properly done:

  1. I verify that the $bloody variable is now set by my own SIGCHLD handler
  2. I verify that the head.dat file was or was not dropped, depending on whether or not the signal was trappable

The reason for this is that there are two signal handlers in play: my dynamic SIGCHLD handler, and the child program’s dynamically defined handler.

The Conclusion

I had a lot of fun putting this one together for ya, it was a blast. I hope that you find reading this code as interesting as I found writing it.
Please also note that I developed this entire program using koding.com. If you think you’d like to use koding.com, check it out. If you click here and sign up, it gives me more disk space to write code with, which enables me to do more of this.
Much thanks!