For an assignment, I am working on creating a time aware shell. The shell forks and executes commands and kills them if they run for more than a set amount of time. For example.
input# /bin/ls
a.out code.c
input# /bin/cat
Error - Expired After 10 Seconds.
input#
Now, my question is: is there a way to prevent the alarm from starting if an error is incurred in the processing of the program, that is, when exevce returns -1?
Since the child-process runs separately and after hours of experimenting and research I have yet to find anything that discusses or even hints at this type of task, I have a feeling it may be impossible. If it is indeed impossible, how can I prevent something like the following from happening...
input# /bin/fgdsfgs
Error executing program
input# Error - Expired After 10 Seconds.
For context, here is the code I am currently working with, with my attempt at doing this myself removed. Thanks for the help in advance!
while(1){
write(1, prompt, sizeof(prompt)); //Prompt user
byteCount = read(0, cmd, 1024); //Retrieve command from user, and count bytes
cmd[byteCount-1] = '\0'; //Prepare command for execution
//Create Thread
child = fork();
if(child == -1){
write(2, error_fork, sizeof(error_fork));
}
if(child == 0){ //Working in child
if(-1 == execve(cmd,arg,env)){ //Execute program or error
write(2, error_exe, sizeof(error_exe));
}
}else if(child != 0){ //Working in the parent
signal(SIGALRM, handler); //Handle the alarm when it goes off
alarm(time);
wait();
alarm(0);
}
}
According to the man page:
Description
The alarm() function shall cause the system to generate a SIGALRM signal for the process after the number of realtime seconds specified by seconds have elapsed. Processor scheduling delays may prevent the process from handling the signal as soon as it is generated.
If seconds is 0, a pending alarm request, if any, is canceled.
Alarm requests are not stacked; only one SIGALRM generation can be scheduled in this manner. If the SIGALRM signal has not yet been generated, the call shall result in rescheduling the time at which the SIGALRM signal is generated.
Interactions between alarm() and any of setitimer(), ualarm(), or usleep() are unspecified.
So, to cancel an alarm: alarm(0)
. It is even present in your sample code.
By the way, you're missing an important piece here:
if(child == 0){ //Working in child
if(-1 == execve(cmd,arg,env)){ //Execute program or error
write(2, error_exe, sizeof(error_exe));
_exit(EXIT_FAILURE); // EXIT OR A FORKED SHELL WILL KEEP GOING
}
}else if(child != 0){ //Working in the parent
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With