From 438dc521bff83743310be60cc50db78ae632e59c Mon Sep 17 00:00:00 2001 From: espie Date: Tue, 30 May 2023 04:42:21 +0000 Subject: [PATCH] Due to the way make is designed, not being able to read a makefile is basically silent. Record errors due to missing permissions and other oddities, and display them when we error out due to lack of targets, as a quality-of-life diagnostic. Based on a remark from sthen@, with some feedback and tweaks from op@ okay op@, kn@ --- usr.bin/make/engine.c | 4 ++- usr.bin/make/main.c | 59 ++++++++++++++++++++++++++++++++++++++++--- usr.bin/make/main.h | 6 ++++- usr.bin/make/parse.c | 3 ++- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/usr.bin/make/engine.c b/usr.bin/make/engine.c index 410dcd0af27..d1967eab92a 100644 --- a/usr.bin/make/engine.c +++ b/usr.bin/make/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.70 2021/10/25 19:54:29 kn Exp $ */ +/* $OpenBSD: engine.c,v 1.71 2023/05/30 04:42:21 espie Exp $ */ /* * Copyright (c) 2012 Marc Espie. * @@ -84,6 +84,7 @@ #include "extern.h" #include "lst.h" #include "timestamp.h" +#include "main.h" #include "make.h" #include "pathnames.h" #include "error.h" @@ -210,6 +211,7 @@ node_failure(GNode *gn) fflush(stdout); else { print_errors(); + dump_unreadable(); Punt(NULL); } } diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 64ea5d27509..93b38671e25 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.129 2023/01/17 13:03:22 kn Exp $ */ +/* $OpenBSD: main.c,v 1.130 2023/05/30 04:42:21 espie Exp $ */ /* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */ /* @@ -87,6 +87,8 @@ bool ignoreErrors; /* -i flag */ bool beSilent; /* -s flag */ bool dumpData; /* -p flag */ +static LIST unreadable; + struct dirs { char *current; char *object; @@ -826,6 +828,48 @@ main(int argc, char **argv) return 0; } +struct unreadable { + char *fname; + int errcode; +}; + +void +dump_unreadable(void) +{ + struct unreadable *u; + + if (Lst_IsEmpty(&unreadable)) + return; + + fprintf(stderr, "Makefile(s) that couldn't be read:\n"); + + while ((u = Lst_Pop(&unreadable))) { + fprintf(stderr, "\t%s: %s\n", u->fname, strerror(u->errcode)); + free(u->fname); + free(u); + } +} + +static FILE * +open_makefile(const char *fname) +{ + FILE *stream; + struct unreadable *u; + + stream = fopen(fname, "r"); + if (stream != NULL) + return stream; + + if (errno != ENOENT) { + u = emalloc(sizeof *u); + u->fname = estrdup(fname); + u->errcode = errno; + Lst_AtEnd(&unreadable, u); + } + + return NULL; +} + /*- * ReadMakefile -- * Open and parse the given makefile. @@ -848,14 +892,14 @@ ReadMakefile(void *p, void *q) Var_Set("MAKEFILE", ""); Parse_File(estrdup("(stdin)"), stdin); } else { - if ((stream = fopen(fname, "r")) != NULL) + if ((stream = open_makefile(fname)) != NULL) goto found; /* if we've chdir'd, rebuild the path name */ if (d->current != d->object && *fname != '/') { char *path; path = Str_concat(d->current, fname, '/'); - if ((stream = fopen(path, "r")) == NULL) + if ((stream = open_makefile(path)) == NULL) free(path); else { fname = path; @@ -866,7 +910,14 @@ ReadMakefile(void *p, void *q) name = Dir_FindFile(fname, userIncludePath); if (!name) name = Dir_FindFile(fname, systemIncludePath); - if (!name || !(stream = fopen(name, "r"))) + if (!name) + return false; + /* do not try to open a file we already have, so that + * dump_unreadable() yields non-confusing results. + */ + if (strcmp(name, fname) == 0) + return false; + if ((stream = open_makefile(name)) == NULL) return false; fname = name; /* diff --git a/usr.bin/make/main.h b/usr.bin/make/main.h index 035de86e602..4106c60daf7 100644 --- a/usr.bin/make/main.h +++ b/usr.bin/make/main.h @@ -1,6 +1,6 @@ #ifndef MAIN_H #define MAIN_H -/* $OpenBSD: main.h,v 1.6 2020/01/13 14:51:50 espie Exp $ */ +/* $OpenBSD: main.h,v 1.7 2023/05/30 04:42:21 espie Exp $ */ /* * Copyright (c) 2001 Marc Espie. @@ -41,4 +41,8 @@ extern Lst create; /* set_notparallel(): used to influence running mode from parse.c */ extern void set_notparallel(void); +/* dump_unreadable: in case of some errors, dump makefile names + * we found but are unable to read. + */ +extern void dump_unreadable(void); #endif diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 1b29df2300b..19f7c83e46f 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.134 2021/03/06 08:31:42 espie Exp $ */ +/* $OpenBSD: parse.c,v 1.135 2023/05/30 04:42:21 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* @@ -1696,6 +1696,7 @@ void Parse_MainName(Lst listmain) /* result list */ { if (mainNode == NULL) { + dump_unreadable(); Punt("no target to make."); /*NOTREACHED*/ } else if (mainNode->type & OP_DOUBLEDEP) { -- 2.20.1