I’m trying to make a simple program using fork() to execute a command or program and see if it finishes under the time limit that I introduce by parameter like this:
Input:
./timechecker 3 ls ps ls
So what I know is that I finished the execlp correctly with the NULL at the end but I don't know why I'm getting random results from the sleep execlp sometimes it says bad address and it says on my output that the programs associated with that run have been forced to finish but it happens independently of the time I use. Example output:
execlp sleep: Bad address //The ls execlp
PID TTY TIME CMD //The ls execlp without sleep error
execlp sleep: Bad address //The ps execlp
225 pts/3 00:00:00 a.out //The ps without sleep error
231 pts/3 00:00:00 ps
232 pts/3 00:00:00 a.out <defunct>
PID TTY TIME CMD
225 pts/3 00:00:00 a.out
233 pts/3 00:00:00 ps
234 pts/3 00:00:00 a.out
Total time: 0
1 programs have been forced to finish taking more than 1000 seg and 2 programs have been finished under the time limit
The code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#define error(a){perror(a);exit(1);}
int main(int argc, char *argv[]) //argv1 timeLimit argv2..argv11 commands
{
if (argc > 12 || argc < 3)
{
error("Incorrect number of arguments");
}
int timeLimit = atoi(argv[1]);
if(timeLimit < 0)
{
error("The time limit must be 0 or greater")
}
int programs = argc - 2;
int forced = 0;
int finished = 0;
char program[100] = "";
int i = 0, pid, pid_clock, pid_dev = 0, estatus;
time_t t1, t2;
t1 = time(NULL);
while(i<programs) //i<nb_tests
{
pid = 0;
pid_clock = 0;
estatus = -1;
t2 = time(NULL);
pid = fork();
switch(pid)
{
case -1:
error("fork")
case 0:
strcpy(program, argv[i]);
execlp(program, program, NULL);
error("execlp programm");
default:
pid_clock = fork();
switch(pid_clock)
{
case -1:
error("fork")
case 0:
execlp("sleep", "sleep", timeLimit, NULL); //The problem
error("execlp sleep");
default:
pid_dev = wait(NULL);
if(pid_dev == pid_clock)
{
kill(pid, SIGKILL);
wait(NULL);
estatus = 0;
break;
}
else if(pid_dev == pid)
{
kill(pid_clock, SIGKILL);
wait(NULL);
estatus = 1;
break;
}
else
{
printf("%d\n", pid_dev);
estatus = -1;
break;
}
}
}
t2 = time(NULL) - t2;
if(estatus == 0)
{
forced++;
}
else if(estatus == 1)
{
finished++;
}
i++;
}
t1 = time(NULL) - t1;
printf("Total time: %li \n", t1);
printf("%d programs have been forced to finish taking more than %d seg and %d programs have been finished under the time limit\n",forced, timeLimit, finished);
return 0;
}
The arguments to the command used for the exec
functions is a list of strings. They are, effectively, what becomes the string array argv
in the executed program.
You pass an integer value as the argument for the sleep
command, not a string. That leads to undefined behavior and very likely crashes.