I'm writing a toy shell program for a class and I did all of my coding on my mac (Darwin 13.4.0) and compiled using gcc <programname> -o <executablename>
. Everything seems to run perfectly. Then I ftp the source code over to the school's Linux server and compile again, using the exact same compilation instruction, but on the Linux machine the code is buggy. In particular, the sigaction (signal handler) doesn't seem to be working properly all the time. It seems as though it isn't reliably catching the SIGCHLD signal. Edit--Actually, what was happening was the variable I was storing the status in was getting clobbered, so the incorrect status was displayed for foreground processes.
Anyone have any ideas why the change in OS might cause this kind of problem?
Here's what my signal handler code looks like:
void handleSignal(int signal){
int childid = 0;
int tempStatus = 0;
while ( (childid = waitpid(-1, &childStatus, WNOHANG)) > 0) {
/*Parse the exit status */
if(WIFEXITED(childStatus)){
childStatus = WEXITSTATUS(childStatus);
}
switch (signal) {
/*if the signal came from a child */
case SIGCHLD:
/*for background processes alert user */
if (childid != foregroundProcess){
printf("pid %i terminated:",childid);
showStatus(childStatus);
fflush(stdout);
}
/* for foreground children ending, just set the temp Status, in case*/
/* background children also need to be caught */
else {
tempStatus = childStatus;
}
break;
case SIGINT:
/*If there is a foreground child, send signal to it, else ignore. */
if (foregroundProcess){
kill(foregroundProcess, signal);
}
break;
default:
printf("Some other signal was received: code %i\n", signal);
fflush(stdout);
}
}
childStatus = tempStatus; /* reset child status to foreground status */
}
Edit: Adding the code that registers the signal handler:
struct sigaction sa;
sa.sa_handler = &handleSignal; /*passing function ref. to handler */
sa.sa_flags = SA_RESTART; /* restart the shell signal handler */
sigfillset(&sa.sa_mask); /*block all other signals while handling sigs */
sigaction(SIGINT, &sa, NULL);
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);