One of the most often cases of signal handling is handling of the children to avoid zombies. This demo launches a child every second; the child simply sleeps 1 to 10 seconds (the particular interval is choosen based on random()) and exits. The main process intercepts SIGCHLD using SUE and prints a message about every finished process.
/* This simple demo program launches a child once a second and looks after existing children using the SUE wait support. */ #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include "sue_sel.hpp" #include "sue_wait.hpp" class ChildHandler : public SUEChildHandler { public: ChildHandler(pid_t a_pid, SUEChildWaitAgent *a_agent) : SUEChildHandler(a_pid, a_agent) {} virtual void ChildHandle() { printf("Process %d finished (%s), status = %d\n", GetPid(), IfExited() ? "exited" : "signaled", ExitCode()); } }; void Launch(SUEChildWaitAgent *agent) { int r; int secs = rand() % 10 + 2; int ecode = rand() % 50; r = fork(); if(r == -1) { perror("fork"); return; } if(r == 0) { /* child */ sleep(secs); exit(ecode); } /* parent */ printf("Launched process %d\n", r); new ChildHandler(r, agent); } class LaunchingTimeout : public SUETimeoutHandler { SUEEventSelector *the_selector; SUEChildWaitAgent *the_agent; // got to remember the agent to call the Launch() function public: LaunchingTimeout(SUEEventSelector *a_sel, SUEChildWaitAgent *a_ag) { the_selector = a_sel; the_agent = a_ag; } ~LaunchingTimeout() {} virtual void TimeoutHandle() { Launch(the_agent); SetFromNow(1); the_selector->RegisterTimeoutHandler(this); } }; int main() { SUEEventSelector selector; SUEChildWaitAgent agent; LaunchingTimeout ltm(&selector, &agent); agent.Register(&selector); ltm.SetFromNow(0); // start right now selector.RegisterTimeoutHandler(<m); printf("Entering the main loop... \n"); selector.Go(); printf("Main loop exited\n"); return 0; }