Subject: Re: Portable NetBSD /bin/sh in pkgsrc/bootstrap
To: Jonathan Perkin <jonathan@perkin.org.uk>
From: Todd Vierling <tv@duh.org>
List: tech-pkg
Date: 03/14/2006 20:53:02
On Tue, 14 Mar 2006, Jonathan Perkin wrote:

> > So this brings back the suggestion I made a while ago for the amd64
> > build: either fixup pdksh or get the NetBSD shell with portability
> > wrappers into pkgsrc. I *really* want to have a reasonable small and
> > fast shell I can depend on.
>
> I like this idea; it would clean up a lot of constructs in pkgsrc
> specifically to handle, how shall we say, "less useful" shells, as well
> as resolving previous concerns we've had about slowing pkgsrc down on
> platforms such as Solaris if we moved to more featureful shell which
> runs slower than the native /bin/sh.

A lot of the stuff there is already portable.  Below are some general diffs
that I used to make NetBSD sh(1) run on Interix.  YMMV with other platforms,
but these diffs may point out where "real" portability constructs, with an
autoconf config file, may be needed.  The addition of the NOEDITLINE checks
may be of particular interest to porting sh.

I used libnbcompat to build and link, with:

CFLAGS+=-DSHELL -I. -I${.CURDIR} -I${.CURDIR}/../libnbcompat/files -DDO_SHAREDVFORK \
        -D_ALL_SOURCE -Wall -include nbcompat.h -pipe -DNOEDITLINE -DSYSV \
        -Dsys_siglist=_sys_siglist -Dsys_signame=_sys_signame \
        -Dintmax_t=long -Duintmax_t=u_long -Dstrtoimax=strtol -Dstrtoumax=strtoul

DO_SHAREDVFORK is really important to get Right.  autoconf has a check for
vfork sharing memory space (I forget the macro name, it might just be
AC_FUNC_VFORK), and that should be used to determine whether or not to use
the DO_SHAREDVFORK code.

As you can see above, the checks for SYSV should be unrolled into
appropriate autoconf checks, and some newer integer constructs from
inttypes.h may need fallbacks.

Index: bin/sh/cd.c
===================================================================
RCS file: /cvsroot/src/bin/sh/cd.c,v
retrieving revision 1.36
diff -u -r1.36 cd.c
--- bin/sh/cd.c	20 Aug 2005 21:07:42 -0000	1.36
+++ bin/sh/cd.c	15 Mar 2006 01:48:21 -0000
@@ -383,7 +383,7 @@
 	 * c implementation of getcwd, that does not open a pipe to
 	 * /bin/pwd.
 	 */
-#if defined(__NetBSD__) || defined(__SVR4)
+#if defined(__NetBSD__) || defined(__SVR4) || defined(__INTERIX)

 	for (i = MAXPWD;; i *= 2) {
 		pwd = stalloc(i);
Index: bin/sh/error.h
===================================================================
RCS file: /cvsroot/src/bin/sh/error.h,v
retrieving revision 1.16
diff -u -r1.16 error.h
--- bin/sh/error.h	7 Aug 2003 09:05:30 -0000	1.16
+++ bin/sh/error.h	15 Mar 2006 01:48:21 -0000
@@ -111,7 +111,7 @@
  * so we use _setjmp instead.
  */

-#if defined(BSD) && !defined(__SVR4)
+#if defined(BSD) && !defined(__SVR4) && !defined(__INTERIX)
 #define setjmp(jmploc)	_setjmp(jmploc)
 #define longjmp(jmploc, val)	_longjmp(jmploc, val)
 #endif
Index: bin/sh/eval.c
===================================================================
RCS file: /cvsroot/src/bin/sh/eval.c,v
retrieving revision 1.84
diff -u -r1.84 eval.c
--- bin/sh/eval.c	23 Jun 2005 23:05:29 -0000	1.84
+++ bin/sh/eval.c	15 Mar 2006 01:48:21 -0000
@@ -50,7 +50,9 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#ifndef __INTERIX
 #include <sys/sysctl.h>
+#endif

 /*
  * Evaluate a command.
@@ -221,7 +223,7 @@
 		exitstatus = 0;
 		goto out;
 	}
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	displayhist = 1;	/* show history substitutions done with fc */
 #endif
 	TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
@@ -604,10 +606,13 @@
 syspath(void)
 {
 	static char *sys_path = NULL;
+#ifndef __INTERIX
 	static int mib[] = {CTL_USER, USER_CS_PATH};
+#endif
 	static char def_path[] = "PATH=/usr/bin:/bin:/usr/sbin:/sbin";
 	size_t len;

+#ifndef __INTERIX
 	if (sys_path == NULL) {
 		if (sysctl(mib, 2, 0, &len, 0, 0) != -1 &&
 		    (sys_path = ckmalloc(len + 5)) != NULL &&
@@ -616,9 +621,12 @@
 		} else {
 			ckfree(sys_path);
 			/* something to keep things happy */
+#endif
 			sys_path = def_path;
+#ifndef __INTERIX
 		}
 	}
+#endif
 	return sys_path;
 }

Index: bin/sh/histedit.c
===================================================================
RCS file: /cvsroot/src/bin/sh/histedit.c,v
retrieving revision 1.37
diff -u -r1.37 histedit.c
--- bin/sh/histedit.c	15 Jul 2005 17:49:43 -0000	1.37
+++ bin/sh/histedit.c	15 Mar 2006 01:48:21 -0000
@@ -58,7 +58,7 @@
 #include "mystring.h"
 #include "myhistedit.h"
 #include "error.h"
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 #include "eval.h"
 #include "memalloc.h"

Index: bin/sh/input.c
===================================================================
RCS file: /cvsroot/src/bin/sh/input.c,v
retrieving revision 1.39
diff -u -r1.39 input.c
--- bin/sh/input.c	7 Aug 2003 09:05:32 -0000	1.39
+++ bin/sh/input.c	15 Mar 2006 01:48:21 -0000
@@ -178,7 +178,7 @@
 	parsenextc = buf;

 retry:
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	if (parsefile->fd == 0 && el) {
 		static const char *rl_cp;
 		static int el_len;
@@ -298,7 +298,7 @@
 	savec = *q;
 	*q = '\0';

-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	if (parsefile->fd == 0 && hist && something) {
 		HistEvent he;
 		INTOFF;
Index: bin/sh/mkbuiltins
===================================================================
RCS file: /cvsroot/src/bin/sh/mkbuiltins,v
retrieving revision 1.21
diff -u -r1.21 mkbuiltins
--- bin/sh/mkbuiltins	6 Jun 2004 07:03:11 -0000	1.21
+++ bin/sh/mkbuiltins	15 Mar 2006 01:48:21 -0000
@@ -106,7 +106,7 @@
 	}
 	echo 'int '"$func"'(int, char **);' >&4
 	while
-		[ $# != 0 -a "$1" != '#' ]
+		[ $# != 0 -a "x$1" != 'x#' ]
 	do
 		[ "$1" = '-s' ] && {
 			specials="$specials $2 $func"
Index: bin/sh/options.c
===================================================================
RCS file: /cvsroot/src/bin/sh/options.c,v
retrieving revision 1.39
diff -u -r1.39 options.c
--- bin/sh/options.c	15 Jul 2005 17:46:54 -0000	1.39
+++ bin/sh/options.c	15 Mar 2006 01:48:21 -0000
@@ -59,7 +59,7 @@
 #include "memalloc.h"
 #include "error.h"
 #include "mystring.h"
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 #include "myhistedit.h"
 #endif
 #include "show.h"
@@ -139,7 +139,7 @@
 optschanged(void)
 {
 	setinteractive(iflag);
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	histedit();
 #endif
 	setjobctl(mflag);
Index: bin/sh/trap.c
===================================================================
RCS file: /cvsroot/src/bin/sh/trap.c,v
retrieving revision 1.33
diff -u -r1.33 trap.c
--- bin/sh/trap.c	15 Jul 2005 17:23:48 -0000	1.33
+++ bin/sh/trap.c	15 Mar 2006 01:48:22 -0000
@@ -61,6 +61,21 @@
 #include "var.h"


+#ifdef __INTERIX
+static int siginterrupt(int sig, int flag) {
+	int ret;
+	struct sigaction act;
+
+	(void) sigaction(sig, NULL, &act);
+	if (flag)
+		act.sa_flags &= ~SA_RESTART;
+	else
+		act.sa_flags |= SA_RESTART;
+	ret = sigaction(sig, &act, NULL);
+	return ret;
+}
+#endif
+
 /*
  * Sigmode records the current value of the signal handlers for the various
  * modes.  A value of zero means that the current handler is not known.
Index: bin/sh/var.c
===================================================================
RCS file: /cvsroot/src/bin/sh/var.c,v
retrieving revision 1.36
diff -u -r1.36 var.c
--- bin/sh/var.c	6 Oct 2004 10:23:43 -0000	1.36
+++ bin/sh/var.c	15 Mar 2006 01:48:22 -0000
@@ -106,7 +106,7 @@
 	{ &vatty,	VSTRFIXED|VTEXTFIXED|VUNSET,	"ATTY=",
 	  NULL },
 #endif
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	{ &vhistsize,	VSTRFIXED|VTEXTFIXED|VUNSET,	"HISTSIZE=",
 	  sethistsize },
 #endif
@@ -125,7 +125,7 @@
 	  NULL },
 	{ &vps4,	VSTRFIXED|VTEXTFIXED,		"PS4=+ ",
 	  NULL },
-#ifndef SMALL
+#if !defined(SMALL) && !defined(NOEDITLINE)
 	{ &vterm,	VSTRFIXED|VTEXTFIXED|VUNSET,	"TERM=",
 	  setterm },
 #endif
Index: bin/test/test.c
===================================================================
RCS file: /cvsroot/src/bin/test/test.c,v
retrieving revision 1.26
diff -u -r1.26 test.c
--- bin/test/test.c	10 Feb 2005 06:56:55 -0000	1.26
+++ bin/test/test.c	15 Mar 2006 01:51:54 -0000
@@ -189,7 +189,9 @@
 {
 	int res;

+#ifndef __INTERIX
 	setprogname(argv[0]);
+#endif
 	if (strcmp(argv[0], "[") == 0) {
 		if (strcmp(argv[--argc], "]"))
 			error("missing ]");
Index: usr.bin/printf/printf.c
===================================================================
RCS file: /cvsroot/src/usr.bin/printf/printf.c,v
retrieving revision 1.31
diff -u -r1.31 printf.c
--- usr.bin/printf/printf.c	22 Mar 2005 23:55:46 -0000	1.31
+++ usr.bin/printf/printf.c	15 Mar 2006 01:47:19 -0000
@@ -50,7 +50,7 @@
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
-#include <inttypes.h>
+/* #include <inttypes.h> */
 #include <limits.h>
 #include <locale.h>
 #include <stdarg.h>
@@ -209,6 +209,7 @@
 				PF(start, p);
 				break;
 			}
+#ifndef __INTERIX
 			case 'b': {
 				/* There has to be a better way to do this,
 				 * but the string we generate might have
@@ -240,6 +241,7 @@
 				printf("%s", b_fmt);
 				break;
 			}
+#endif
 			case 'c': {
 				char p = getchr();
 				PF(start, p);

-- 
-- Todd Vierling <tv@duh.org> <tv@pobox.com> <todd@vierling.name>