cprocessexecsetrlimit

Set time limit to a child process


I'm creating a shell and have a problem when creating my own ulimit function : I want to limit the time of a process, and I use setrlimit for it. But it seems that when I call execvp then, the time limit is kind of erased.

In this example code, when I let the while(1), the child process receives a SIGXCPU and is killed after 3 seconds. But when I do execvp(...) instead, it's never killed.

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(void) {
    struct rlimit t = {3, 8};

    uint32_t child_pid = fork();

    // father
    if (child_pid != 0) {
        waitpid(child_pid, NULL, 0);

    // child
    } else {
        setrlimit(RLIMIT_CPU, &t);
        char* s[3];
        s[0] = "sleep";
        s[1] = "1000";
        s[2] = NULL;

        /* while(1); */
        execvp(*s, s);
    }
}

If I'm right and the time limit I set with setrlimit is erased, how to do it then ?

Thanks for help.


Solution

  • I want to limit the time of a process, and I use setrlimit for it. But it seems that when I call execvp then, the time limit is kind of erased.

    That would be contrary to the POSIX specifications for the exec-family functions, and contrary to the Linux documentation for setrlimit(). Both say that resource limits are preserved across an exec. Linux claims its implementation is consistent also with the BSDs. In other words, what you suggest is highly unlikely to be an accurate characterization of what's happening.

    Basically, you are not testing what you think you are testing. You are setting a resource limit on CPU time, but the process you're testing on is sleep, which for all intents and purposes does not consume any CPU time. Of course it never receives a SIGXCPU as a result of the resource limit you've set.

    CPU time is not at all the same thing as wall time, and the latter is not a managed resource. If you want the child to receive a signal after a set amount of wall time, then use the alarm() function (whose count-down timer is also inherited across an exec).