sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit f7f69125cf296bfd50a483c976f0991ec6e9ffe1
parent f8d39b2329be259e46efd019091e6061de5fbe4b
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:
Mmake/main.c | 1+
Mmake/make.h | 55++++++++++++++++++++++++++++---------------------------
Mmake/posix.c | 35+++++++++++++++++++++++++++++------
Mmake/rules.c | 9+++++----
4 files changed, 63 insertions(+), 37 deletions(-)

diff --git a/make/main.c b/make/main.c @@ -90,6 +90,7 @@ estrdup(char *s) void sighandler(int signo) { + killchild(); stop = signo; } 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; 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; } 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