URI:
       Avoid race conditions between fork and wait - utmp - simple login manager  
  HTML git clone git://git.suckless.org/utmp
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 836feec54d58f145d34b14baee7cb0ff677cbd26
   DIR parent c282965520a0d8bcc2b8c2f010fd96ad063a25c3
  HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Thu,  7 Aug 2014 14:52:19 +0200
       
       Avoid race conditions between fork and wait
       
       If some signal arrives to the parent between these two points
       then it is possible to have dirty entries in utmp.
       
       Diffstat:
         M utmp.c                              |      17 +++++++++++++----
       
       1 file changed, 13 insertions(+), 4 deletions(-)
       ---
   DIR diff --git a/utmp.c b/utmp.c
       @@ -6,6 +6,7 @@
        #include <stdlib.h>
        #include <stdio.h>
        #include <string.h>
       +#include <signal.h>
        
        #include <sys/types.h>
        #include <unistd.h>
       @@ -39,6 +40,7 @@ main(int argc, char *argv[])
        {
                int status;
                uid_t uid;
       +        sigset_t set;
                extern void addutmp(void), delutmp(void);
        
                egid = getegid();
       @@ -54,8 +56,12 @@ main(int argc, char *argv[])
                setenv("SHELL", pass->pw_shell, 0);
                setenv("HOME", pass->pw_dir, 0);
        
       +        sigfillset(&set);
       +        sigprocmask(SIG_BLOCK, &set, NULL);
       +
                switch (fork()) {
                case 0:
       +                sigprocmask(SIG_UNBLOCK, &set, NULL);
                        argv[0] = getenv("SHELL");
                        execv(argv[0], argv);
                        die("error executing shell:%s", strerror(errno));
       @@ -63,10 +69,13 @@ main(int argc, char *argv[])
                        die("error spawning child:%s", strerror(errno));
                default:
                        addutmp();
       -                if (wait(&status) == -1) {
       -                        fprintf(stderr, "error waiting child:%s\n",
       -                                strerror(errno));
       -                }
       +                signal(SIGINT, SIG_IGN);
       +                signal(SIGTERM, SIG_IGN);
       +                signal(SIGHUP, SIG_IGN);
       +                sigprocmask(SIG_UNBLOCK, &set, NULL);
       +
       +                if (wait(&status) == -1)
       +                        perror("error waiting child");
                        delutmp();
                }
                return 0;