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.
I want to limit the time of a process, and I use
setrlimit
for it. But it seems that when I callexecvp
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).