Subject: make: add ksh spec and have compat mode use default shell
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@crufty.net>
List: tech-toolchain
Date: 07/30/2003 22:49:47
The patch below adds a spec for ksh so that it can be selected as the
default shell with just:

.SHELL: name=ksh

That's simple enough... possibly more contentious is having compat
mode use the default shell spec (typically Bourne shell).
This allows one to use .SHELL: to control the shell that will be used
by compat mode.

The goal is to allow folk trying to build pkgsrc on non-BSD platforms
to overcome some of the modern features used in our makefiles that are
not supported by the native /bin/sh.
Obviously this patch is mostly of value to bmake - but since its
totally generic I figured changing make is the go.

Thoughts?
--sjg

Index: compat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/compat.c,v
retrieving revision 1.45
diff -u -p -r1.45 compat.c
--- compat.c	2003/07/14 18:19:11	1.45
+++ compat.c	2003/07/31 05:48:17
@@ -259,8 +259,12 @@ CompatRunCommand(ClientData cmdp, Client
 	 * -e flag as well as -c if it's supposed to exit when it hits an
 	 * error.
 	 */
-	static const char *shargv[4] = { _PATH_BSHELL };
+	static const char *shargv[4];
 
+	shargv[0] = shellPath;
+	/*
+	 * The following work for any of the builtin shell specs.
+	 */
 	if (DEBUG(SHELL))
 		shargv[1] = (errCheck ? "-exc" : "-xc");
 	else
@@ -549,6 +553,8 @@ Compat_Run(Lst targs)
     const char    *cp;	    /* Pointer to string of shell meta-characters */
     GNode   	  *gn = NULL;/* Current root target */
     int	    	  errors;   /* Number of targets not remade due to errors */
+
+    Shell_Init();		/* setup default shell */
 
     if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
 	signal(SIGINT, CompatInterrupt);
Index: config.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/config.h,v
retrieving revision 1.14
diff -u -p -r1.14 config.h
--- config.h	2002/01/16 03:40:29	1.14
+++ config.h	2003/07/31 05:48:17
@@ -40,7 +40,9 @@
  *	from: @(#)config.h	8.1 (Berkeley) 6/6/93
  */
 
+#ifndef DEFSHELL
 #define	DEFSHELL	1			/* Bourne shell */
+#endif
 
 /*
  * DEFMAXJOBS
Index: job.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/job.c,v
retrieving revision 1.80
diff -u -p -r1.80 job.c
--- job.c	2003/07/16 07:16:24	1.80
+++ job.c	2003/07/31 05:48:20
@@ -209,6 +209,16 @@ static Shell    shells[] = {
     "e",
 },
     /*
+     * KSH description. 
+     */
+{
+    "ksh",
+    TRUE, "set +v", "set -v", "set +v", 6,
+    TRUE, "set -e", "set +e",
+    "v",
+    "e",
+},
+    /*
      * UNKNOWN.
      */
 {
@@ -223,10 +233,10 @@ static Shell 	*commandShell = &shells[DE
 						   * commands in the Makefile.
 						   * It is set by the
 						   * Job_ParseShell function */
-static const char *shellPath = NULL,		  /* full pathname of
+const char *shellPath = NULL,		  	  /* full pathname of
 						   * executable image */
-               	*shellName = NULL,	      	  /* last component of shell */
-		*shellArgv = NULL;		  /* Custom shell args */
+           *shellName = NULL;		      	  /* last component of shell */
+static const char *shellArgv = NULL;		  /* Custom shell args */
 
 
 static int  	maxJobs;    	/* The most children we can run at once */
@@ -2531,6 +2541,28 @@ Job_Make(GNode *gn)
     (void) JobStart(gn, 0, NULL);
 }
 
+void
+Shell_Init()
+{
+    if (shellPath == NULL) {
+	/*
+	 * The user didn't specify a shell to use, so we are using the
+	 * default one... Both the absolute path and the last component
+	 * must be set. The last component is taken from the 'name' field
+	 * of the default shell description pointed-to by commandShell.
+	 * All default shells are located in _PATH_DEFSHELLDIR.
+	 */
+	shellName = commandShell->name;
+	shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+    }
+    if (commandShell->exit == NULL) {
+	commandShell->exit = "";
+    }
+    if (commandShell->echo == NULL) {
+	commandShell->echo = "";
+    }
+}
+
 /*-
  *-----------------------------------------------------------------------
  * Job_Init --
@@ -2581,24 +2613,7 @@ Job_Init(int maxproc, int maxlocal)
 	targFmt = TARG_FMT;
     }
 
-    if (shellPath == NULL) {
-	/*
-	 * The user didn't specify a shell to use, so we are using the
-	 * default one... Both the absolute path and the last component
-	 * must be set. The last component is taken from the 'name' field
-	 * of the default shell description pointed-to by commandShell.
-	 * All default shells are located in _PATH_DEFSHELLDIR.
-	 */
-	shellName = commandShell->name;
-	shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
-    }
-
-    if (commandShell->exit == NULL) {
-	commandShell->exit = "";
-    }
-    if (commandShell->echo == NULL) {
-	commandShell->echo = "";
-    }
+    Shell_Init();
 
     if (pipe(exit_pipe) < 0)
 	Fatal("error in pipe: %s", strerror(errno));
Index: job.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/job.h,v
retrieving revision 1.18
diff -u -p -r1.18 job.h
--- job.h	2003/07/14 18:19:12	1.18
+++ job.h	2003/07/31 05:48:20
@@ -231,6 +231,9 @@ typedef struct Shell {
     const char   *exit;		/* exit on error */
 }               Shell;
 
+extern const char *shellPath;
+extern const char *shellName;
+
 extern int	job_pipe[2];	/* token pipe for jobs. */
 extern int	jobTokensRunning; /* tokens currently "out" */
 extern int	jobTokensFree;	/* tokens free but not yet released to pipe */
@@ -251,6 +254,7 @@ extern Lst  	stoppedJobs;	/* List of job
 				 * quite get started */
 #endif
 
+void Shell_Init(void);
 void Job_Touch(GNode *, Boolean);
 Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
 void Job_CatchChildren(Boolean);
Index: main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/main.c,v
retrieving revision 1.89
diff -u -p -r1.89 main.c
--- main.c	2003/07/14 18:19:12	1.89
+++ main.c	2003/07/31 05:48:22
@@ -1224,10 +1224,12 @@ Cmd_Exec(const char *cmd, const char **e
 
     *err = NULL;
 
+    if (!shellName)
+	Shell_Init();
     /*
      * Set up arguments for shell
      */
-    args[0] = "sh";
+    args[0] = shellName;
     args[1] = "-c";
     args[2] = cmd;
     args[3] = NULL;
@@ -1258,7 +1260,7 @@ Cmd_Exec(const char *cmd, const char **e
 	(void) dup2(fds[1], 1);
 	(void) close(fds[1]);
 
-	(void) execv(_PATH_BSHELL, UNCONST(args));
+	(void) execv(shellPath, UNCONST(args));
 	_exit(1);
 	/*NOTREACHED*/