I'm trying to have it execute in a loop where the parent randomly picks between SIGUSR1 and SIGUSR2 and send it to the child process to receive and write to a file
My problem is the signal will only send in the first loop and after that it stops
int main(int argc, char* argv[], char *envp[]){
time_t start, finish; //for example purposes, to save the time
struct sigaction sact; //signal action structure
sact.sa_handler = &handler;
sact.sa_handler = &handler2;
sigset_t new_set, old_set; //signal mask data-types
FILE *file = fopen("received_signal.txt", "w");
fprintf(file,"%s\t %s\t %s\n", "Signal Type",
"Signal Time", "thread ID");
fclose(file);
int pid;
int cpid;
pid = fork();
if(pid == 0){//recieves
//sigaction(SIGUSR1, &sact, NULL);
while(1){
signal(SIGUSR1, handler);
signal(SIGUSR2, handler2);
sleep(1);
}
} else{ //generates
while(1){
sleep(1); // give child time to spawn
printf("hello\n");
parent_func(0);
//wait(NULL);
usleep(((rand() % 5) 1) * 10000);
}
}
return 0;
}
void parent_func(int child_pid){
srand(time(NULL));
int rnd = rand();
int result = (rnd & 1) ? 2 : 1;
struct timeval t;
gettimeofday(&t, NULL);
unsigned long time = 1000000 * t.tv_sec t.tv_usec;
printf("result: %d\n", result);
printf("time: %ld\n", time);
if(result == 1){
//sigaction(SIGUSR1, &sact, NULL);
kill(child_pid, SIGUSR1);
log(SIGUSR1);
} else{
//sigaction(SIGUSR2, &sact, NULL);
kill(child_pid, SIGUSR2);
log(SIGUSR2);
}
}
void handler(int sig){
if (sig == SIGUSR1){
puts("child received SIGUSR1");
}
}
void handler2(int sig){
if (sig == SIGUSR2){
puts("child received SIGUSR2");
}
}
Tried throwing the child in a while loop to get it to repeat but no such luck
CodePudding user response:
man signal(2) tells you that the handler is reset to SIG_DFL once a signal is delivered:
If the disposition is set to a function, then first either the disposition is reset to SIG_DFL, or the signal is blocked (see Portability below), and then handler is called with argument signum. If invocation of the handler caused the signal to be blocked, then the signal is unblocked upon return from the handler.
I suggest you use sigaction instead of signal:
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 199309L
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
void handler(int sig) {
char s[] = "child received signal SIGUSR?\n";
char *s2 = strchr(s, '?');
*s2 = sig == SIGUSR1 ? '1' : '2';
write(STDOUT_FILENO, s, strlen(s));
}
int main(int argc, char* argv[], char *envp[]){
pid_t child_pid = fork();
if(!child_pid) {
struct sigaction sa = {
.sa_handler = &handler
};
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL);
for(;;) {
sleep(1);
}
return 0;
}
for(;;) {
sleep(1);
int s = (int []){SIGUSR1, SIGUSR2}[rand() % 2];
printf("parent sending signal %d to %d\n", s, child_pid);
kill(child_pid, s);
}
}
and sample output:
parent sending signal 12 to 521586
child received signal SIGUSR2
parent sending signal 10 to 521586
child received signal SIGUSR1
parent sending signal 12 to 521586
child received signal SIGUSR2
parent sending signal 12 to 521586
child received signal SIGUSR2