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.
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 aSIGXCPUas 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).