Take the 2-minute tour ×

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.

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!

    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
share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

According to the man page:






So, to cancel an alarm: alarm(0). It is even present in your sample code.

The main problem

By the way, you're missing an important piece here:

        write(2, error_exe, sizeof(error_exe));
share|improve this answer
Right, the alarm(0) that is in my code successfully cancels the alarm when the child process executes successfully; so that when a command executes before the x seconds timer expires the alarm doesn't go off. Unfortunately though, this is not the behavior that occurs when the process cannot be executed. Edit: Thanks for that second tip! –  Suki Apr 19 '12 at 23:57
I just realised that after answering. But the lack of exit() when execve() fails seems to be the hint. –  C2H5OH Apr 19 '12 at 23:59
If execve fails, you must _exit not exit. The latter is usually unsafe. –  R.. Apr 20 '12 at 1:13
@R..: Well, if there weren't any actions hooked with atexit() the difference between those is subtle. But I'll edit the answer anyway because, as you said, it is a better choice in this case (+1 for you). –  C2H5OH Apr 20 '12 at 9:19
add comment

The wait() system call takes an argument; why aren't you compiling with the right headers in the source file and with compiler warnings (preferably errors) for undeclared functions? Or, if you are getting such warnings, pay heed to them before submitting code for review on places like StackOverflow.

You don't need to test the return status from execve() (or any of the exec*() functions); if it returns, it failed.

It is good to write an error on failure. It would be better if the child process exited as well, so that it doesn't go back into the while (1) loop, competing with your main shell for input data.

if (child == 0)
    execve(cmd, arg, env);
    write(2, error_exe, sizeof(error_exe));
    exit((errno == ENOEXEC) ? 126 : 127);

In fact, the non-exiting of your child is the primary cause of your problem; the wait doesn't return until the alarm goes off because the child hasn't exited. The exit statuses shown are intended to match the POSIX shell specification.

share|improve this answer
add comment

Your Answer


