I'm trying to call a function everytime my child process dies. This is done by catching the SIGCHLD sent by execve(). My problem here is that my handler function is not always called a second time. Sometimes it is though so I'm a bit confused.
My code is this one:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // sigaction()
#include <time.h>
#include <errno.h>
#include <unistd.h>
#define MAX_LENGTH 1000
#define BILLION 1E9
struct timespec start,stop;
float totalTime = 0;
void runCommand(int signo)
{
printf("Run command called\n");
float processTime = 0;
//Get the time when the process ended
if(clock_gettime(CLOCK_MONOTONIC,&stop) == -1){
perror(NULL);
}
processTime = stop.tv_sec - start.tv_sec + ( stop.tv_nsec - start.tv_nsec ) / BILLION;
totalTime += processTime;
}
int main(int argc, char const *argv[]) {
int counter = 0;
int pid = 0;
int status;
char *args[4];
char line[MAX_LENGTH];
//Setup behaviour for SIGCHLD
struct sigaction psa;
psa.sa_handler = runCommand;
sigaction(SIGCHLD, &psa, NULL);
FILE *fp = fopen("script_file.txt","r");
if(!fp)
{
return 0;
}
//Setup argsgcc
args[0] = "/bin/sh";
args[1] = "-c";
args[3] = NULL;
while(fgets(line, MAX_LENGTH, fp))
{
printf("The command number %d is %s \n", counter, line);
//Get the time when the process started
if(clock_gettime(CLOCK_MONOTONIC,&start) == -1){
perror(NULL);
}
//Create a new process
pid = fork();
//Child process
if(pid == 0)
{
args[2] = line;
execve("/bin/sh", args, NULL);
}
//Parent process
else
{
wait(&status);
}
counter++;
}
printf("The overall time was %f seconds.\n", totalTime);
fclose(fp);
return 0;
}
When I try to run it sometimes my result is:
The command number 0 is mkdir test/
Run command called
The command number 1 is sleep 0.5
Run command called
The command number 2 is sleep 1
Run command called
The command number 3 is rmdir test/
Run command called
The overall time was 1.544909 seconds.
Which seems correct. But in other instances my result is:
The command number 0 is mkdir test/
Run command called
The command number 1 is sleep 0.5
The command number 2 is sleep 1
The command number 3 is rmdir test/
The overall time was 0.009810 seconds.
This makes me believe that sigaction is not always receiving my SIGCHLD signal. When I run valgrind I get the following error:
==5407== All heap blocks were freed -- no leaks are possible
==5407==
==5407== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==5407==
==5407== 1 errors in context 1 of 2:
==5407== Syscall param rt_sigaction(act->sa_flags) points to uninitialised byte(s)
==5407== at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==5407== by 0x40098B: main (iv.c:40)
==5407== Address 0xffefff498 is on thread 1's stack
==5407== Uninitialised value was created by a stack allocation
==5407== at 0x400931: main (iv.c:29)
==5407==
==5407==
==5407== 1 errors in context 2 of 2:
==5407== Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s)
==5407== at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==5407== by 0x40098B: main (iv.c:40)
==5407== Address 0xffefff4a8 is on thread 1's stack
==5407== Uninitialised value was created by a stack allocation
==5407== at 0x400931: main (iv.c:29)
==5407==
==5407== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
But I'm not sure what this means.