clinuxtimerforksetitimer

Is setitimer() call inherited by children


I'm writing a code forking (number of 3, 5, ... indefinite number). I wish my program to end after the time specified(parent kills firstly its children then itself probably by calling _exit which is also sig-safe). I mean in signal handler I kill whole children by kill() then call waitpid() for all since both are kind of async-signal-safe function. To do that, I'm using setitimer(ITIMER_REAL, &timer, NULL before forking.

So is it inherited by the forked children?

If it is not inherited, could you show a source?

If it is inherited, do all children end as well after the time is taken? In addition, actually I don't want the case.


Solution

  • Not inherited.

    The POSIX spec for fork explicitly mentions that timers are not inherited and that XSI (timer_create/timer_settime) timers are reset:

    • [XSI] [Option Start] Interval timers shall be reset in the child process. [Option End]
    • Per-process timers created by the parent shall not be inherited by the child process.

    A test program like:

    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/time.h>
    
    void h(int Sig)
    {
        char pid[20];
        sprintf(pid,"%d\n",(int)getpid());
        (void)write(1,pid,strlen(pid));
    }
    int main()
    {
        if(0>sigaction(SIGALRM,&(struct sigaction){.sa_handler=h},0)) return perror("sigaction"),1;
        if(0>setitimer(ITIMER_REAL, &(struct itimerval){.it_value.tv_sec=1},0)) return perror("setitimer"),1;
        pid_t ch; if(0>(ch=fork())) return perror("fork"),1;
        pause();
        if(ch){
            sleep(1);
            kill(ch,SIGTERM);
        }
        _exit(0);
    }
    

    shows the handler runs only in the parent—it prints only one pid.