I'm trying to handle multiple signals with one signal handler, the expected result is for ctrlc to exit the child process and also exit the parent process while ctrlz prints a random number everytime ctrlz is pressed but it doesn't seem to work after the first signal is handled.The other part of the code is a child process that loops until ctrl-c is called. This is the code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <time.h>
#include <string.h>
int sig_ctrlc = 0;
int sig_ctrlz = 0;
//main signal handler to handle all signals
void SIGhandler(int sig) {
switch (sig) {
case SIGINT:
sig_ctrlc = SIGINT;
break;
case SIGTSTP:
sig_ctrlz = SIGTSTP;
break;
case SIGCHLD:
default: break;
}
}
int main() {
int fd[2]; //to store the two ends of the pipe
char get_inode[] = "ls -il STATUS.TXT";
FILE *fp;
FILE *log;
FILE *command;
time_t t;
time(&t);
int rv = 0;
log = fopen("file_log.txt", "w");
struct sigaction act;
memset (&act, 0, sizeof(struct sigaction));
act.sa_handler = SIGhandler;
//if pipe can't be created
if (pipe(fd) < 0) {
fprintf(log, "Pipe error");
}
int pid = fork();
switch(pid) {
case -1:
fprintf(stderr, "fork failed\n");
exit(1);
case 0:
/*child process */
// maps STDOUT to the writing end of the pipe
// if (dup2(fd[1], STDOUT_FILENO) == -1) {
// fprintf(log, "error in mapping stdout to the writing pipe\n");
// }
act.sa_flags = SA_RESTART;
sigemptyset(&act.sa_mask);
sigaction(SIGINT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
for (size_t i = 1;; i++) {
/* code */
printf(" running in child\n");
sleep(1);
if (sig_ctrlc != 0) {
printf("ctrlc handled\n");
printf("exiting...\n");
sig_ctrlc = 0;
break;
}
if (sig_ctrlz != 0) {
printf("ctlrz handled.\n");
/* random generator, the problem with this is it runs with time if ctrlz
is handled within a second it returns the same number
*/
srand(time(0));
int rand_num;
rand_num = rand() % (50 - 10 + 1) + 10;
printf("random number: %d\n", rand_num);
sig_ctrlz = 0;
sigaction(SIGINT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
}
}
default:
/* parent process */
close(fd[1]);
//maps STDIN to the reading end of the pipe
// if (dup2(fd[0], STDIN_FILENO) < 0) {
// fprintf(log, "can't redirect");
// exit(1);
// }
// //checks for fopen not working and writes to STATUS.TXT with a redirect
// if ((fp = freopen("STATUS.TXT", "w", stdout)) != NULL) {
// printf("start time of program: %s\n", ctime(&t));
// printf("Parent process ID: %d\n", getppid());
// printf("Child process ID: %d\n", getpid());
//
// //gets inode information sends the command to and receives the info from the terminal
// command = popen(get_inode, "w");
// fprintf(command, "STATUS.TXT");
// fclose(command);
//
//// map STDOUT to the status file
// if(freopen("STATUS.TXT", "a+ ", stdout) == NULL) {
// fp = fopen("file_log.txt","w");
// fprintf(log, "can't map STATUS.TXT to stdout\n");
// exit(1);
// }
//
printf("parent has started\n");
wait(NULL);
time(&t);
printf("PARENT: My child's termination status is: %d at: %s\n", WEXITSTATUS(rv), ctime(&t));
// fprintf(fp, "PARENT: My child's termination status is: %d at: %s\n", WEXITSTATUS(rv), ctime(&t));
// fclose(fp);
// fclose(log);
sigaction(SIGINT, &act, NULL);
for (size_t i = 1;; i++) {
/* code */
printf("PARENT: in parent function\n");
sleep(1);
if (sig_ctrlc != 0)
exit(0);
}
}
return 0;
}