scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit b2d141b26dec9b355c67e319f8771b07cf2d99aa
parent 1d704cf0b2455ad6c5f9a70769d5175c6ca09689
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 10 Jan 2025 10:19:39 +0100

make: Do not remove directory targets

As specified by the POSIX specification:

	If not already ignored, make shall trap SIGHUP, SIGTERM, SIGINT,
	and SIGQUIT and remove the current target unless the target
	is a directory or the target is a prerequisite of the special
	target .PRECIOUS or unless one of the -n, -p, or -q options
	was specified.	Any targets removed in this manner shall be
	reported in diagnostic messages of unspecified format, written
	to standard error.  After this cleanup process, if any, make
	shall take the standard action for all other signals.

Diffstat:
Msrc/cmd/scc-make/make.h | 1+
Msrc/cmd/scc-make/posix.c | 12++++++++++++
Msrc/cmd/scc-make/rules.c | 2+-
Atests/make/execute/0102-signal.sh | 37+++++++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/cmd/scc-make/make.h b/src/cmd/scc-make/make.h @@ -70,6 +70,7 @@ extern time_t stamp(char *); extern int launch(char *, int); extern int putenv(char *); extern void exportvar(char *, char *); +extern int is_dir(char *); /* main.c */ extern int kflag, dflag, nflag, iflag, sflag; diff --git a/src/cmd/scc-make/posix.c b/src/cmd/scc-make/posix.c @@ -11,6 +11,18 @@ #include "make.h" +int +is_dir(char *fname) +{ + struct stat st; + + if (stat(fname, &st) < 0) { + perror("make: cheking if target is a dir"); + return 0; + } + return (st.st_mode & S_IFMT) == S_IFDIR; +} + void exportvar(char *var, char *value) { diff --git a/src/cmd/scc-make/rules.c b/src/cmd/scc-make/rules.c @@ -454,7 +454,7 @@ cleanup(Target *tp) } } - if (!precious && !nflag && !qflag) { + if (!precious && !nflag && !qflag && !is_dir(tp->name)) { printf("make: trying to remove target %s\n", tp->name); remove(tp->name); } diff --git a/tests/make/execute/0102-signal.sh b/tests/make/execute/0102-signal.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +cleanup() +{ + rm -rf adir + kill -KILL $pid 2>/dev/null + if test $1 -ne 0 + then + kill -KILL $$ + fi +} + +rm -rf adir +trap 'cleanup 0' EXIT +trap 'cleanup 1' INT TERM HUP + +scc-make -f - <<'EOF' 2>&1 & +adir: + @mkdir $@ + @while : ; do sleep 1 ; done +EOF + +pid=$! + +sleep 10 && echo timeout >&2 && kill $$ 2>/dev/null & + +while : +do + if test -d adir + then + kill $pid 2>/dev/null + wait $pid + break + fi +done + +test -d adir