Reputation: 13
I have a program that starts a child (r.out
), and that child has a time limit.
I want to know how to stop running r.out
after passing the time limit.
I am running the code on Linux.
This is what I have so far:
#include <unistd.h>
#include <signal.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#define TIME_LIMIT 1 //determine time limit
void my_function(); //supposed to include the submitted code
void alarm_handler(int);
int main()
{
if (sigaction(SIGALRM, NULL, NULL) == -1)
err(1, NULL);
signal(SIGALRM, alarm_handler); // assigning an alarm handler for SIGALRM
alarm(TIME_LIMIT); // install an alarm to be fired after TIME_LIMIT
system("./r.out"); //Running the file
alarm(0);
return 0;
}
void alarm_handler(int sig)
{
printf("%s" , "Time limit exceeded");
//Here i want a code to stop the r.out file
}
Upvotes: 1
Views: 5589
Reputation: 223947
In order to kill the child, you need to know its pid. You can get it if you start the program with fork
and exec
instead of system
.
In addition to a signal handler for SIGALRM
, set up one for SIGCHLD
(received when a child process finishes) as well. After calling alarm
to set the timer, call pause
. This function will return when you get either of the two signals.
In the signal handlers you should only set a global flag. Calling printf
from within a signal handler can lead to undefined behavior.
After pause
returns, check each of the two flags. If the timeout flag is set, you can terminate the child with kill
.
In either case, call wait
to reap the child process's pid.
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define TIME_LIMIT 1 //determine time limit
void alarm_handler(int);
void child_handler(int);
int timeout = 0;
int child_done = 0;
int main()
{
pid_t pid = fork();
if (pid == -1) {
perror("fork failed");
exit(1);
} else if (pid == 0) {
// child process
execl("./r.out","r.out", NULL);
perror("exec failed");
_exit(1);
}
// set up the signal handlers after forking so the child doesn't inherit them
signal(SIGALRM, alarm_handler);
signal(SIGCHLD, child_handler);
alarm(TIME_LIMIT); // install an alarm to be fired after TIME_LIMIT
pause();
if (timeout) {
printf("alarm triggered\n");
int result = waitpid(pid, NULL, WNOHANG);
if (result == 0) {
// child still running, so kill it
printf("killing child\n");
kill(pid, 9);
wait(NULL);
} else {
printf("alarm triggered, but child finished normally\n");
}
} else if (child_done) {
printf("child finished normally\n");
wait(NULL);
}
return 0;
}
void child_handler(int sig)
{
child_done = 1;
}
void alarm_handler(int sig)
{
timeout = 1;
}
Upvotes: 1