URI:
       make: Synchronize with scc - sbase - suckless unix tools
  HTML git clone git://git.suckless.org/sbase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit f7f69125cf296bfd50a483c976f0991ec6e9ffe1
   DIR parent f8d39b2329be259e46efd019091e6061de5fbe4b
  HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
       Date:   Wed, 31 Dec 2025 15:31:21 +0100
       
       make: Synchronize with scc
       
       Scc fixed a race condition hapenning while forking and execing the command
       and receiving a signal that could keep make waiting forever. Signals
       are correctly masked now to avoid this problems.
       
       Diffstat:
         M make/main.c                         |       1 +
         M make/make.h                         |      55 ++++++++++++++++---------------
         M make/posix.c                        |      35 +++++++++++++++++++++++++------
         M make/rules.c                        |       9 +++++----
       
       4 files changed, 63 insertions(+), 37 deletions(-)
       ---
   DIR diff --git a/make/main.c b/make/main.c
       @@ -90,6 +90,7 @@ estrdup(char *s)
        void
        sighandler(int signo)
        {
       +        killchild();
                stop = signo;
        }
        
   DIR diff --git a/make/make.h b/make/make.h
       @@ -43,35 +43,36 @@ struct target {
                struct target *next;
        };
        
       -extern void *emalloc(size_t);
       -extern void *erealloc(void *, size_t);
       -extern char *estrdup(char *);
       -
       -extern void dumprules(void);
       -extern void dumpmacros(void);
       -
       -extern char *expandstring(char *, Target *, struct loc *);
       -extern void addtarget(char *, int);
       -extern void inject(char *);
       -extern int build(char *);
       -extern int hash(char *);
       -extern int parse(char *);
       -extern void debug(char *, ...);
       -extern void error(char *, ...);
       -extern void warning(char *, ...);
       -extern void adddep(char *, char *);
       -extern void addrule(char *, struct action *, int);
       -extern void freeloc(struct loc *);
       -
       -extern char *getmacro(char *);
       -extern void setmacro(char *, char *, int, int);
       +void *emalloc(size_t);
       +void *erealloc(void *, size_t);
       +char *estrdup(char *);
       +
       +void dumprules(void);
       +void dumpmacros(void);
       +
       +char *expandstring(char *, Target *, struct loc *);
       +void addtarget(char *, int);
       +void inject(char *);
       +int build(char *);
       +int hash(char *);
       +int parse(char *);
       +void debug(char *, ...);
       +void error(char *, ...);
       +void warning(char *, ...);
       +void adddep(char *, char *);
       +void addrule(char *, struct action *, int);
       +void freeloc(struct loc *);
       +
       +char *getmacro(char *);
       +void setmacro(char *, char *, int, int);
        
        /* system depdendant */
       -extern time_t stamp(char *);
       -extern int launch(char *, int);
       -extern int putenv(char *);
       -extern void exportvar(char *, char *);
       -extern int is_dir(char *);
       +void killchild(void);
       +time_t stamp(char *);
       +int launch(char *, int);
       +int putenv(char *);
       +void exportvar(char *, char *);
       +int is_dir(char *);
        
        /* main.c */
        extern int kflag, dflag, nflag, iflag, sflag;
   DIR diff --git a/make/posix.c b/make/posix.c
       @@ -12,6 +12,17 @@
        
        #include "make.h"
        
       +
       +static volatile pid_t pid;
       +
       +void
       +killchild(void)
       +{
       +        if (pid != 0)
       +                kill(pid, SIGTERM);
       +        pid = 0;
       +}
       +
        int
        is_dir(char *fname)
        {
       @@ -49,14 +60,13 @@ int
        launch(char *cmd, int ignore)
        {
                int st;
       -        pid_t pid;
       +        sigset_t new, old;
                char *name, *shell;
                char *args[] = {NULL, "-ec" , cmd, NULL};
                static int initsignals;
                extern char **environ;
                extern void sighandler(int);
        
       -
                if (!initsignals) {
                        struct sigaction act = {
                                .sa_handler = sighandler
       @@ -70,10 +80,25 @@ launch(char *cmd, int ignore)
                        initsignals = 1;
                }
        
       +        sigfillset(&new);
       +        sigprocmask(SIG_BLOCK, &new, &old);
       +        if (stop)
       +                goto unblock;
       +
                switch (pid = fork()) {
                case -1:
       +                perror("make");
       +        unblock:
       +                sigprocmask(SIG_SETMASK, &old, NULL);
                        return -1;
                case 0:
       +                signal(SIGINT, SIG_DFL);
       +                signal(SIGHUP, SIG_DFL);
       +                signal(SIGTERM, SIG_DFL);
       +                signal(SIGQUIT, SIG_DFL);
       +
       +                sigprocmask(SIG_SETMASK, &old, NULL);
       +
                        shell = getmacro("SHELL");
        
                        if (ignore)
       @@ -86,10 +111,8 @@ launch(char *cmd, int ignore)
                        execve(shell, args, environ);
                        _exit(127);
                default:
       -                if (wait(&st) < 0) {
       -                        kill(pid, SIGTERM);
       -                        wait(&st);
       -                }
       +                sigprocmask(SIG_SETMASK, &old, NULL);
       +                wait(&st);
        
                        return st;
                }
   DIR diff --git a/make/rules.c b/make/rules.c
       @@ -62,10 +62,11 @@ lookup(char *name)
        static void
        cleanup(Target *tp)
        {
       -        int precious;
       +        int sig, precious;
                Target *p, **q;
        
       -        printf("make: signal %d arrived\n", stop);
       +        sig = stop;
       +        printf("make: signal %d arrived\n", sig);
        
                precious = 0;
                p = lookup(".PRECIOUS");
       @@ -81,8 +82,8 @@ cleanup(Target *tp)
                        remove(tp->name);
                }
        
       -        signal(stop, SIG_DFL);
       -        raise(stop);
       +        signal(sig, SIG_DFL);
       +        raise(sig);
        }
        
        static int