Module Name:    src
Committed By:   sjg
Date:           Thu Nov 12 23:35:21 UTC 2020

Modified Files:
        src/usr.bin/make: main.c make.1 make.h parse.c
        src/usr.bin/make/unit-tests: Makefile
Added Files:
        src/usr.bin/make/unit-tests: objdir-writable.exp objdir-writable.mk

Log Message:
Pass a writable flag to Main_SetObjdir to control writable check

For curdir and an explicit .OBJDIR target, we allow for
the directory to be read-only.
During InitObjdir we otherwise default to requiring objdir to be
writable - this can be controlled by env variable
MAKE_OBJDIR_CHECK_WRITABLE

Add unit-tests/objdir-writable

Reviewed by: christos rillig


To generate a diff of this commit:
cvs rdiff -u -r1.455 -r1.456 src/usr.bin/make/main.c
cvs rdiff -u -r1.290 -r1.291 src/usr.bin/make/make.1
cvs rdiff -u -r1.205 -r1.206 src/usr.bin/make/make.h
cvs rdiff -u -r1.437 -r1.438 src/usr.bin/make/parse.c
cvs rdiff -u -r1.197 -r1.198 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/objdir-writable.exp \
    src/usr.bin/make/unit-tests/objdir-writable.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.455 src/usr.bin/make/main.c:1.456
--- src/usr.bin/make/main.c:1.455	Sun Nov  8 23:38:02 2020
+++ src/usr.bin/make/main.c	Thu Nov 12 23:35:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.455 2020/11/08 23:38:02 rillig Exp $	*/
+/*	$NetBSD: main.c,v 1.456 2020/11/12 23:35:21 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -109,7 +109,7 @@
 #include "trace.h"
 
 /*	"@(#)main.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: main.c,v 1.455 2020/11/08 23:38:02 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.456 2020/11/12 23:35:21 sjg Exp $");
 #if defined(MAKE_NATIVE) && !defined(lint)
 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
 	    "The Regents of the University of California.  "
@@ -710,7 +710,7 @@ Main_ParseArgLine(const char *line)
 }
 
 Boolean
-Main_SetObjdir(const char *fmt, ...)
+Main_SetObjdir(Boolean writable, const char *fmt, ...)
 {
 	struct stat sb;
 	char *path;
@@ -730,8 +730,7 @@ Main_SetObjdir(const char *fmt, ...)
 
 	/* look for the directory and try to chdir there */
 	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
-		/* if not .CURDIR it must be writable */
-		if ((strcmp(path, curdir) != 0 && access(path, W_OK) != 0) ||
+		if ((writable && access(path, W_OK) != 0) ||
 		    (chdir(path) != 0)) {
 			(void)fprintf(stderr, "make warning: %s: %s.\n",
 			    path, strerror(errno));
@@ -751,7 +750,7 @@ Main_SetObjdir(const char *fmt, ...)
 }
 
 static Boolean
-Main_SetVarObjdir(const char *var, const char *suffix)
+Main_SetVarObjdir(Boolean writable, const char *var, const char *suffix)
 {
 	void *path_freeIt;
 	const char *path = Var_Value(var, VAR_CMDLINE, &path_freeIt);
@@ -772,7 +771,7 @@ Main_SetVarObjdir(const char *var, const
 		xpath = xpath_freeIt;
 	}
 
-	(void)Main_SetObjdir("%s%s", xpath, suffix);
+	(void)Main_SetObjdir(writable, "%s%s", xpath, suffix);
 
 	bmake_free(xpath_freeIt);
 	bmake_free(path_freeIt);
@@ -1093,15 +1092,18 @@ ignore_pwd:
 static void
 InitObjdir(const char *machine, const char *machine_arch)
 {
+	Boolean writable;
+
 	Dir_InitDir(curdir);
-	(void)Main_SetObjdir("%s", curdir);
+	writable = GetBooleanVar("MAKE_OBJDIR_CHECK_WRITABLE", TRUE);
+	(void)Main_SetObjdir(FALSE, "%s", curdir);
 
-	if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
-	    !Main_SetVarObjdir("MAKEOBJDIR", "") &&
-	    !Main_SetObjdir("%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
-	    !Main_SetObjdir("%s.%s", _PATH_OBJDIR, machine) &&
-	    !Main_SetObjdir("%s", _PATH_OBJDIR))
-		(void)Main_SetObjdir("%s%s", _PATH_OBJDIRPREFIX, curdir);
+	if (!Main_SetVarObjdir(writable, "MAKEOBJDIRPREFIX", curdir) &&
+	    !Main_SetVarObjdir(writable, "MAKEOBJDIR", "") &&
+	    !Main_SetObjdir(writable, "%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
+	    !Main_SetObjdir(writable, "%s.%s", _PATH_OBJDIR, machine) &&
+	    !Main_SetObjdir(writable, "%s", _PATH_OBJDIR))
+		(void)Main_SetObjdir(writable, "%s%s", _PATH_OBJDIRPREFIX, curdir);
 }
 
 /* get rid of resource limit on file descriptors */

Index: src/usr.bin/make/make.1
diff -u src/usr.bin/make/make.1:1.290 src/usr.bin/make/make.1:1.291
--- src/usr.bin/make/make.1:1.290	Sun Nov  1 20:24:45 2020
+++ src/usr.bin/make/make.1	Thu Nov 12 23:35:21 2020
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.290 2020/11/01 20:24:45 rillig Exp $
+.\"	$NetBSD: make.1,v 1.291 2020/11/12 23:35:21 sjg Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"	from: @(#)make.1	8.4 (Berkeley) 3/19/94
 .\"
-.Dd November 1, 2020
+.Dd November 12, 2020
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -1089,6 +1089,15 @@ to the specified directory if it exists,
 and
 .Ql Ev PWD
 to that directory before executing any targets.
+.Pp
+Except in the case of an explicit
+.Ql Ic .OBJDIR
+target, 
+.Nm
+will check that the specified directory is writable and ignore it if not.
+This check can be skipped by setting the environment variable
+.Ql Ev MAKE_OBJDIR_CHECK_WRITABLE
+to "no".
 .
 .It Va .PARSEDIR
 A path to the directory of the current

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.205 src/usr.bin/make/make.h:1.206
--- src/usr.bin/make/make.h:1.205	Tue Nov 10 00:32:12 2020
+++ src/usr.bin/make/make.h	Thu Nov 12 23:35:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.205 2020/11/10 00:32:12 rillig Exp $	*/
+/*	$NetBSD: make.h,v 1.206 2020/11/12 23:35:21 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -652,7 +652,7 @@ Boolean Make_Run(GNodeList *);
 Boolean shouldDieQuietly(GNode *, int);
 void PrintOnError(GNode *, const char *);
 void Main_ExportMAKEFLAGS(Boolean);
-Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
+Boolean Main_SetObjdir(Boolean, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
 int mkTempFile(const char *, char **);
 int str2Lst_Append(StringList *, char *, const char *);
 void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);

Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.437 src/usr.bin/make/parse.c:1.438
--- src/usr.bin/make/parse.c:1.437	Sun Nov  8 23:38:02 2020
+++ src/usr.bin/make/parse.c	Thu Nov 12 23:35:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.437 2020/11/08 23:38:02 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.438 2020/11/12 23:35:21 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -117,7 +117,7 @@
 #include "pathnames.h"
 
 /*	"@(#)parse.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: parse.c,v 1.437 2020/11/08 23:38:02 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.438 2020/11/12 23:35:21 sjg Exp $");
 
 /* types and constants */
 
@@ -1429,7 +1429,7 @@ ParseDoDependencySourceSpecial(ParseSpec
 	Suff_SetNull(word);
 	break;
     case SP_OBJDIR:
-	Main_SetObjdir("%s", word);
+	Main_SetObjdir(FALSE, "%s", word);
 	break;
     default:
 	break;

Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.197 src/usr.bin/make/unit-tests/Makefile:1.198
--- src/usr.bin/make/unit-tests/Makefile:1.197	Tue Nov 10 22:23:37 2020
+++ src/usr.bin/make/unit-tests/Makefile	Thu Nov 12 23:35:21 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.197 2020/11/10 22:23:37 rillig Exp $
+# $NetBSD: Makefile,v 1.198 2020/11/12 23:35:21 sjg Exp $
 #
 # Unit tests for make(1)
 #
@@ -188,6 +188,7 @@ TESTS+=		modmatch
 TESTS+=		modmisc
 TESTS+=		modts
 TESTS+=		modword
+TESTS+=		objdir-writable
 TESTS+=		opt
 TESTS+=		opt-backwards
 TESTS+=		opt-chdir
@@ -379,10 +380,16 @@ TESTS+=		varparse-mod
 TESTS+=		varparse-undef-partial
 TESTS+=		varquote
 
+.if ${.OBJDIR} != ${.CURDIR}
+RO_OBJDIR:=	${.OBJDIR}/roobj
+.else
+RO_OBJDIR:=	${TMPDIR:U/tmp}/roobj
+.endif
 # Additional environment variables for some of the tests.
 # The base environment is -i PATH="$PATH".
 ENV.depsrc-optional+=   TZ=UTC
 ENV.envfirst=		FROM_ENV=value-from-env
+ENV.objdir-writable+=	RO_OBJDIR=${RO_OBJDIR}
 ENV.varmisc=		FROM_ENV=env
 ENV.varmisc+=		FROM_ENV_BEFORE=env
 ENV.varmisc+=		FROM_ENV_AFTER=env
@@ -409,6 +416,7 @@ SED_CMDS.job-output-long-lines= \
 	${:D marker should always be at the beginning of the line. } \
 	-e '/^aa*--- job-b ---$$/d' \
 	-e '/^bb*--- job-a ---$$/d'
+SED_CMDS.objdir-writable= -e 's,${RO_OBJDIR},OBJDIR/roobj,g'
 SED_CMDS.opt-debug-graph1= \
 			-e 's,${.CURDIR},CURDIR,'
 SED_CMDS.opt-debug-graph1+= \

Added files:

Index: src/usr.bin/make/unit-tests/objdir-writable.exp
diff -u /dev/null src/usr.bin/make/unit-tests/objdir-writable.exp:1.1
--- /dev/null	Thu Nov 12 23:35:21 2020
+++ src/usr.bin/make/unit-tests/objdir-writable.exp	Thu Nov 12 23:35:21 2020
@@ -0,0 +1,5 @@
+make warning: OBJDIR/roobj: Permission denied.
+/tmp
+OBJDIR/roobj
+OBJDIR/roobj
+exit status 0
Index: src/usr.bin/make/unit-tests/objdir-writable.mk
diff -u /dev/null src/usr.bin/make/unit-tests/objdir-writable.mk:1.1
--- /dev/null	Thu Nov 12 23:35:21 2020
+++ src/usr.bin/make/unit-tests/objdir-writable.mk	Thu Nov 12 23:35:21 2020
@@ -0,0 +1,27 @@
+# $NetBSD: objdir-writable.mk,v 1.1 2020/11/12 23:35:21 sjg Exp $
+
+# test checking for writable objdir
+
+RO_OBJDIR?= ${TMPDIR:U/tmp}/roobj
+
+.if make(do-objdir)
+# this should succeed
+.OBJDIR: ${RO_OBJDIR}
+
+do-objdir:
+.else
+all: no-objdir ro-objdir explicit-objdir
+
+# make it now
+x!= echo; mkdir -p ${RO_OBJDIR};  chmod 555 ${RO_OBJDIR}
+
+no-objdir:
+	@MAKEOBJDIR=${RO_OBJDIR} ${.MAKE} -r -f /dev/null -C /tmp -V .OBJDIR
+
+ro-objdir:
+	@MAKEOBJDIR=${RO_OBJDIR} ${.MAKE} -r -f /dev/null -C /tmp -V .OBJDIR MAKE_OBJDIR_CHECK_WRITABLE=no
+
+explicit-objdir:
+	@${.MAKE} -r -f ${MAKEFILE} -C /tmp do-objdir -V .OBJDIR
+.endif
+

Reply via email to