Hi,
I'm having a problem with my C code. I have a program that fork()'s a child process. The child process waits a time period defined by command line parameter, then alarms the parent process.
Now, the program has to handle SIGUSR1 and SIGUSR2 signals too. The first one should pause the child process, and the second one should continue it to count from the point it was paused. For example, if the program is started with parameter "30", and SIGUSR1 is sent in 13 seconds, the alarm would "freeze" at 13, and after SIGUSR2, it would continue counting for another 17 seconds before alarming the parent.
So far, I haven't had any luck. Either I get a segmentation fault or the child process dies before the parent process.
Here's my (dirty) code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
pid_t pid;
int paused = 0;
int newtime;
void signalhandler(int sig) {
int c_status;
wait(&c_status);
printf("Signalhandler: Lapsiprosessi %d suljettiin.\n", sig);
}
void killhandler(int sig) {
printf("Killhandlerissa...\n");
kill(0, SIGTERM);
}
// Välittää signaalin lapsiprosessille
void userhandler(int sig) {
printf("Saatiin signaali %d\n", sig);
kill(pid, sig);
if(sig == SIGUSR1) pause();
}
void child_pausehandler(int sig) {
if(sig == SIGUSR1) {
printf("Lapsi: Sain signaalin %d! Pitää pysähtyä!\n", sig);
paused = 1;
pause();
}else if(sig == SIGUSR2) {
printf("Lapsi: Sain signaalin %d! Nyt jatketaan!\n", sig);
alarm(newtime);
paused = 0;
pause();
}
}
int main(int argc, char* argv[]) {
newtime = atoi(argv[1]);
int status;
if(argc != 2) {
printf("Käyttö: %s aika\n", argv[0]);
return 1;
}
struct sigaction child_action;
child_action.sa_handler = signalhandler;
sigaction(SIGALRM, &child_action, NULL);
struct sigaction kill_action;
kill_action.sa_handler = killhandler;
sigaction(SIGTERM, &kill_action, NULL);
if((pid = fork()) == -1) {
printf("Virhe forkatessa.\n");
return 1;
}
if(pid == 0) {
/*
struct sigaction pause_action;
pause_action.sa_handler = child_pausehandler;
sigaction(SIGUSR1, &pause_action, NULL);
*/
struct sigaction child_pauseaction;
child_pauseaction.sa_handler = child_pausehandler;
sigaction(SIGUSR1, &child_pauseaction, NULL);
sigaction(SIGUSR2, &child_pauseaction, NULL);
printf("Minä olen lapsi, ja minun pid on %d.\n", getpid());
printf("Odotetaan %d sekuntia.\n", atoi(argv[1]));
while(paused == 0) {
newtime = alarm(newtime);
pause();
}
//exit(0);
}else{
struct sigaction user_action;
user_action.sa_handler = userhandler;
sigaction(SIGUSR1, &user_action, NULL);
sigaction(SIGUSR2, &user_action, NULL);
printf("Minä olen äiti, ja minun pid on %d\n", getpid());
int s;
s = wait(&status);
status /= 256;
if(status == 0) {
printf("Lapsiprosessi %d kuoli normaalisti (status %d)\n", s, status);
}else{
printf("Lapsiproseesi %d ei päättynyt normaalisti (status: %d)\n", s, status);
}
}
return 0;
}