[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

es-0.68



Here is a set of patches to bring up es from 0.67 to 0.68.

Changes include:

	verbose gc debugging

	conditional use of "sig_atomic_t", for non-ANSI environments

	conditional use of Reiser-cpp semantics for token pasting
		and string-izing

	fix for gc foward() of a vector (this fixes most, if not
		all, of the crashes that were reported)

	added GCDEBUG support for sun memory protection
		(via valloc & mprotect)

	fixed a couple of omissions in initial.es

	fix for a word consing bug in the parser

	fix for a redirection node bug in the parser

	initial.es now runs after exception handlers have been
		enabled

[Editorial note: I don't know if fixes #2 & #3 are enough to make
es work with unproto; I haven't got the time to waste on games like
that. My sympathy for people who have hardware that can run an ANSI
compiler, be it gcc, but who refuse to deal with ANSI code on the basis
of their religion is absolutely nil. I am not in the religion
business---i.e., I have no problem helping people get the job done,
such as compiling on the antiquated OS of an obscure machine (though I
am not willing to make this a priority effort), but there is no way
that I am going to make appeasing the religious qualms of the ANSI
snobs a priority in any way whatsoever. Whew. Enough said.]

Byron.

[Chris: can you put this in the ftp directory as diffs-0.67-0.68,
please?]

diff -rc ../orig/config.h ./config.h
*** ../orig/config.h	Thu Oct  1 00:25:39 1992
--- ./config.h	Wed Oct  7 09:21:59 1992
***************
*** 13,18 ****
--- 13,23 ----
   *		immediate crash.  requires os/mmu support for enabling and
   *		disabling access to pages.
   *
+  *	GCVERBOSE
+  *		if this is on, it is possible to run the garbage collector
+  *		in a mode where it explains what it is doing at all times.
+  *		implied by GCDEBUG.
+  *
   *	PROTECT_ENV
   *		if on, makes all variable names in the environment ``safe'':
   *		that is, makes sure no characters other than c identifier
***************
*** 64,70 ****
  
  #if NeXT
  #define	DEFAULT_USE_DIRENT	0
! #define DEFAULT_USE_SIG_ATOMIC_T 1
  #endif
  
  
--- 69,75 ----
  
  #if NeXT
  #define	DEFAULT_USE_DIRENT	0
! #define	DEFAULT_USE_SIG_ATOMIC_T 1
  #endif
  
  
***************
*** 124,131 ****
  #define	DEFAULT_JOB_PROTECT	1
  #endif
  
! #ifndef DEFAULT_USE_SIG_ATOMIC_T
! #define DEFAULT_USE_SIG_ATOMIC_T 0
  #endif
  
  /*
--- 129,136 ----
  #define	DEFAULT_JOB_PROTECT	1
  #endif
  
! #ifndef	DEFAULT_USE_SIG_ATOMIC_T
! #define	DEFAULT_USE_SIG_ATOMIC_T 0
  #endif
  
  /*
***************
*** 140,145 ****
--- 145,154 ----
  #define	GCDEBUG		DEFAULT_GCDEBUG
  #endif
  
+ #ifndef	GCVERBOSE
+ #define	GCVERBOSE	DEFAULT_GCVERBOSE
+ #endif
+ 
  #ifndef	PROTECT_ENV
  #define	PROTECT_ENV	DEFAULT_PROTECT_ENV
  #endif
***************
*** 168,173 ****
  #define	JOB_PROTECT	DEFAULT_JOB_PROTECT
  #endif
  
! #ifndef USE_SIG_ATOMIC_T
! #define USE_SIG_ATOMIC_T DEFAULT_USE_SIG_ATOMIC_T
  #endif
--- 177,192 ----
  #define	JOB_PROTECT	DEFAULT_JOB_PROTECT
  #endif
  
! #ifndef	USE_SIG_ATOMIC_T
! #define	USE_SIG_ATOMIC_T DEFAULT_USE_SIG_ATOMIC_T
! #endif
! 
! 
! /*
!  * enforcing choices that must be made
!  */
! 
! #if	GCDEBUG && !GCVERBOSE
! #undef	GCVERBOSE
! #define	GCVERBOSE	1
  #endif
diff -rc ../orig/es.h ./es.h
*** ../orig/es.h	Thu Oct  1 00:25:39 1992
--- ./es.h	Wed Oct  7 09:21:59 1992
***************
*** 26,31 ****
--- 26,39 ----
  #define arraysize(a)		((int)(sizeof(a)/sizeof(*a)))
  #define	memzero(dest, count)	memset(dest, 0, count)
  
+ #if REISER_CPP
+ #define CONCAT(a,b)	a/**/b
+ #define STRING(s)	"s"
+ #else
+ #define CONCAT(a,b)	a ## b
+ #define STRING(s)	#s
+ #endif
+ 
  #if __GNUC__
  typedef volatile void noreturn;
  #else
***************
*** 32,38 ****
  typedef void noreturn;
  #endif
  
! #if GCDEBUG && NeXT
  #define	ABORT()	asm("trap #15")	/* (*(char *) 0 = 'c'); */
  #else
  #define	ABORT()	abort()
--- 40,46 ----
  typedef void noreturn;
  #endif
  
! #if NeXT
  #define	ABORT()	asm("trap #15")	/* (*(char *) 0 = 'c'); */
  #else
  #define	ABORT()	abort()
***************
*** 43,49 ****
  	do { \
  		if (!(expr)) { \
  			eprint("%s:%d: assertion failed (%s)\n", \
! 					__FILE__, __LINE__, #expr); \
  			ABORT(); \
  		} \
  	} while (0)
--- 51,57 ----
  	do { \
  		if (!(expr)) { \
  			eprint("%s:%d: assertion failed (%s)\n", \
! 					__FILE__, __LINE__, STRING(expr)); \
  			ABORT(); \
  		} \
  	} while (0)
***************
*** 158,164 ****
  };
  
  typedef struct {
! 	int len;
  	char *vector[1];
  } Vector;			/* environment or arguments */
  
--- 166,172 ----
  };
  
  typedef struct {
! 	int alloclen, count;
  	char *vector[1];
  } Vector;			/* environment or arguments */
  
***************
*** 175,181 ****
  extern Boolean verbose;			/* -v */
  extern Boolean printcmds;		/* -x */
  
! extern Boolean gcdebug;			/* -G */
  extern Boolean bugme;			/* -B */
  
  
--- 183,189 ----
  extern Boolean verbose;			/* -v */
  extern Boolean printcmds;		/* -x */
  
! extern Boolean gcverbose;		/* -G */
  extern Boolean bugme;			/* -B */
  
  
***************
*** 382,388 ****
  /* gc.c -- see gc.h for more */
  
  typedef struct Tag Tag;
! #define	gcnew(type)	((type *) gcalloc(sizeof (type), &type ## Tag))
  
  extern void *gcalloc(size_t n, Tag *t);		/* allocate n with collection tag t */
  extern char *gcdup(const char *s);		/* copy a 0-terminated string into gc space */
--- 390,396 ----
  /* gc.c -- see gc.h for more */
  
  typedef struct Tag Tag;
! #define	gcnew(type)	((type *) gcalloc(sizeof (type), CONCAT(&type, Tag)))
  
  extern void *gcalloc(size_t n, Tag *t);		/* allocate n with collection tag t */
  extern char *gcdup(const char *s);		/* copy a 0-terminated string into gc space */
***************
*** 413,433 ****
  #define	Ref(t, v, init) \
  	do { \
  		t v = init; \
! 		Root (__root__ ## v); \
! 		(__root__ ## v).p = (void **) &v; \
! 		(__root__ ## v).next = rootlist; \
! 		rootlist = &(__root__ ## v)
  #define	RefPop(v) \
! 		assert(rootlist == &(__root__ ## v)); \
  		assert(rootlist->p == (void **) &v); \
  		rootlist = rootlist->next;
  #define RefEnd(v) \
! 		assert(rootlist == &(__root__ ## v)); \
  		assert(rootlist->p == (void **) &v); \
  		RefPop(v); \
  	} while (0)
  #define RefReturn(v)	/* { */	\
! 		assert(rootlist == &(__root__ ## v)); \
  		assert(rootlist->p == (void **) &v); \
  		RefPop(v); \
  		return v; \
--- 421,441 ----
  #define	Ref(t, v, init) \
  	do { \
  		t v = init; \
! 		Root (CONCAT(__root__, v)); \
! 		(CONCAT(__root__, v)).p = (void **) &v; \
! 		(CONCAT(__root__, v)).next = rootlist; \
! 		rootlist = &(CONCAT(__root__, v))
  #define	RefPop(v) \
! 		assert(rootlist == &(CONCAT(__root__, v))); \
  		assert(rootlist->p == (void **) &v); \
  		rootlist = rootlist->next;
  #define RefEnd(v) \
! 		assert(rootlist == &(CONCAT(__root__, v))); \
  		assert(rootlist->p == (void **) &v); \
  		RefPop(v); \
  	} while (0)
  #define RefReturn(v)	/* { */	\
! 		assert(rootlist == &(CONCAT(__root__, v))); \
  		assert(rootlist->p == (void **) &v); \
  		RefPop(v); \
  		return v; \
diff -rc ../orig/gc.c ./gc.c
*** ../orig/gc.c	Thu Oct  1 00:25:37 1992
--- ./gc.c	Wed Oct  7 09:22:00 1992
***************
*** 41,50 ****
   * debugging
   */
  
! #if GCDEBUG
! #define	DEBUG(p)	if (!gcdebug) ; else eprint p ;
  #else
! #define	DEBUG(p)	do {} while (0)
  #endif
  
  
--- 41,50 ----
   * debugging
   */
  
! #if GCVERBOSE
! #define	VERBOSE(p)	if (!gcverbose) ; else eprint p ;
  #else
! #define	VERBOSE(p)	do {} while (0)
  #endif
  
  
***************
*** 125,135 ****
  
  /* take -- allocate memory for a space */
  static void *take(size_t n) {
  	/* TODO: sun take */
  }
  
! /* revalidate -- enable access to a range of memory */
  static void release(void *p, size_t n) {
  	/* TODO: sun release */
  }
  
--- 125,137 ----
  
  /* take -- allocate memory for a space */
  static void *take(size_t n) {
+ 	return valloc(n);
  	/* TODO: sun take */
  }
  
! /* release -- deallocate a range of memory */
  static void release(void *p, size_t n) {
+ 	free(n);
  	/* TODO: sun release */
  }
  
***************
*** 286,292 ****
  	if (!isinspace(old, p))
  		return p;
  
! 	DEBUG(("GC %8ux : ", p));
  
  	tag = TAG(p);
  	assert(tag != NULL);
--- 288,294 ----
  	if (!isinspace(old, p))
  		return p;
  
! 	VERBOSE(("GC %8ux : ", p));
  
  	tag = TAG(p);
  	assert(tag != NULL);
***************
*** 293,303 ****
  	if (FORWARDED(tag)) {
  		np = FOLLOW(tag);
  		assert(TAG(np)->magic == TAGMAGIC);
! 		DEBUG(("%s	-> %8ux (followed)\n", TAG(np)->typename, np));
  	} else {
  		assert(tag->magic == TAGMAGIC);
  		np = (*tag->copy)(p);
! 		DEBUG(("%s	-> %8ux (forwarded)\n", tag->typename, np));
  		TAG(p) = FOLLOWTO(np);
  	}
  	return np;
--- 295,305 ----
  	if (FORWARDED(tag)) {
  		np = FOLLOW(tag);
  		assert(TAG(np)->magic == TAGMAGIC);
! 		VERBOSE(("%s	-> %8ux (followed)\n", TAG(np)->typename, np));
  	} else {
  		assert(tag->magic == TAGMAGIC);
  		np = (*tag->copy)(p);
! 		VERBOSE(("%s	-> %8ux (forwarded)\n", tag->typename, np));
  		TAG(p) = FOLLOWTO(np);
  	}
  	return np;
***************
*** 319,325 ****
  			Tag *tag = *(Tag **) scan;
  			assert(tag->magic == TAGMAGIC);
  			scan += sizeof (Tag *);
! 			DEBUG(("GC %8ux : %s	scan\n", scan, tag->typename));
  			scan += ALIGN((*tag->scan)(scan));
  		}
  		if (sp == new)
--- 321,327 ----
  			Tag *tag = *(Tag **) scan;
  			assert(tag->magic == TAGMAGIC);
  			scan += sizeof (Tag *);
! 			VERBOSE(("GC %8ux : %s	scan\n", scan, tag->typename));
  			scan += ALIGN((*tag->scan)(scan));
  		}
  		if (sp == new)
***************
*** 376,391 ****
  #else
  		new = newspace(NULL);
  #endif
! 		DEBUG(("\nGC collection starting\n"));
! 		DEBUG(("GC old space = %ux ... %ux\n", old->bot, old->current));
! 		DEBUG(("GC new space = %ux ... %ux\n", new->bot, new->current));
! 		DEBUG(("GC scanning root list\n"));
  		scanroots(rootlist);
! 		DEBUG(("GC scanning global root list\n"));
  		scanroots(globalrootlist);
! 		DEBUG(("GC scanning new space\n"));
  		scanspace();
! 		DEBUG(("GC collection done\n\n"));
  
  		deprecate(old);
  		old = NULL;
--- 378,393 ----
  #else
  		new = newspace(NULL);
  #endif
! 		VERBOSE(("\nGC collection starting\n"));
! 		VERBOSE(("GC old space = %ux ... %ux\n", old->bot, old->current));
! 		VERBOSE(("GC new space = %ux ... %ux\n", new->bot, new->current));
! 		VERBOSE(("GC scanning root list\n"));
  		scanroots(rootlist);
! 		VERBOSE(("GC scanning global root list\n"));
  		scanroots(globalrootlist);
! 		VERBOSE(("GC scanning new space\n"));
  		scanspace();
! 		VERBOSE(("GC collection done\n\n"));
  
  		deprecate(old);
  		old = NULL;
***************
*** 422,428 ****
  /* gcalloc -- allocate an object in new space */
  extern void *gcalloc(size_t nbytes, Tag *tag) {
  	size_t n = ALIGN(nbytes + sizeof (Tag *));
! #if GCDEBUG || GCALWAYS
  	gc();
  #endif
  	assert(tag == NULL || tag->magic == TAGMAGIC);
--- 424,430 ----
  /* gcalloc -- allocate an object in new space */
  extern void *gcalloc(size_t nbytes, Tag *tag) {
  	size_t n = ALIGN(nbytes + sizeof (Tag *));
! #if GCDEBUG
  	gc();
  #endif
  	assert(tag == NULL || tag->magic == TAGMAGIC);
***************
*** 513,519 ****
  }
  
  
! #if GCDEBUG
  /*
   * memdump -- print out all of gc space, as best as possible
   */
--- 515,521 ----
  }
  
  
! #if GCVERBOSE
  /*
   * memdump -- print out all of gc space, as best as possible
   */
diff -rc ../orig/gc.h ./gc.h
*** ../orig/gc.h	Thu Oct  1 00:25:39 1992
--- ./gc.h	Wed Oct  7 09:22:00 1992
***************
*** 30,36 ****
  
  extern Tag StringTag;
  
! #define	DefineTag(t)	Tag t ## Tag = { t ## Copy, t ## Scan, TAGMAGIC, #t }
  
  /*
   * allocation
--- 30,36 ----
  
  extern Tag StringTag;
  
! #define	DefineTag(t)	Tag CONCAT(t, Tag) = { CONCAT(t, Copy), CONCAT(t, Scan), TAGMAGIC, STRING(t) }
  
  /*
   * allocation
diff -rc ../orig/glob.c ./glob.c
*** ../orig/glob.c	Thu Oct  1 00:25:37 1992
--- ./glob.c	Wed Oct  7 09:22:00 1992
***************
*** 30,38 ****
  static List *listsort(List *list) {
  	if (length(list) > 1) {
  		Vector *v = vectorize(list);
! 		qsort(v->vector, v->len, sizeof (char *), qstrcmp);
  		gcdisable(0);
! 		Ref(List *, lp, listify(v->len, v->vector));
  		gcenable();
  		list = lp;
  		RefEnd(lp);
--- 30,38 ----
  static List *listsort(List *list) {
  	if (length(list) > 1) {
  		Vector *v = vectorize(list);
! 		qsort(v->vector, v->count, sizeof (char *), qstrcmp);
  		gcdisable(0);
! 		Ref(List *, lp, listify(v->count, v->vector));
  		gcenable();
  		list = lp;
  		RefEnd(lp);
diff -rc ../orig/initial.es ./initial.es
*** ../orig/initial.es	Thu Oct  1 00:25:37 1992
--- ./initial.es	Wed Oct  7 09:22:01 1992
***************
*** 37,42 ****
--- 37,43 ----
  fn-exec		= $&exec
  fn-exit		= $&exit
  fn-false	= $&false
+ fn-fork		= $&fork
  fn-if		= $&if
  fn-newpgrp	= $&newpgrp
  fn-noexport	= $&noexport
***************
*** 76,78 ****
--- 77,80 ----
  ifs = ' ' \t \n
  prompt = ';; ' ''
  home = /		# so home definitely exists, even if wrong
+ cdpath = ''
diff -rc ../orig/main.c ./main.c
*** ../orig/main.c	Thu Oct  1 00:25:38 1992
--- ./main.c	Wed Oct  7 09:22:02 1992
***************
*** 9,15 ****
  Boolean printcmds	= FALSE;	/* -x */
  
  Boolean bugme		= FALSE;	/* -B */
! Boolean gcdebug		= FALSE;	/* -G */
  
  static const char initial[] =
  #include "initial.h"
--- 9,15 ----
  Boolean printcmds	= FALSE;	/* -x */
  
  Boolean bugme		= FALSE;	/* -B */
! Boolean gcverbose	= FALSE;	/* -G */
  
  static const char initial[] =
  #include "initial.h"
***************
*** 58,67 ****
  	List *e;
  	int c;
  
- 	const char *volatile cmd = NULL;	/* -c */
- 	Boolean protected = FALSE;		/* -p */
  	Boolean keepclosed = FALSE;		/* -o */
! 	Boolean allowquit = FALSE;		/* -d */
  	volatile Boolean stdin = FALSE;		/* -s */
  
  	initgc();
--- 58,67 ----
  	List *e;
  	int c;
  
  	Boolean keepclosed = FALSE;		/* -o */
! 	const char *volatile cmd = NULL;	/* -c */
! 	volatile Boolean protected = FALSE;	/* -p */
! 	volatile Boolean allowquit = FALSE;	/* -d */
  	volatile Boolean stdin = FALSE;		/* -s */
  
  	initgc();
***************
*** 94,100 ****
  		default:
  			usage();
  		case 'D':	bugme = TRUE;		break;
! 		case 'G':	gcdebug = TRUE;		break;
  		}
  
  getopt_done:
--- 94,100 ----
  		default:
  			usage();
  		case 'D':	bugme = TRUE;		break;
! 		case 'G':	gcverbose = TRUE;	break;
  		}
  
  getopt_done:
***************
*** 107,117 ****
  	if (cmd == NULL && (optind == argc || stdin) && !interactive && isatty(0))
  		interactive = TRUE;
  
- 	initinput();
- 	initprims();
- 	initvars(envp, initial, protected);
- 	initsignals(allowquit);
- 
  	if (
  		(setjmp(childhandler.label) && (e = exception) != NULL)
  	     || (e = pushhandler(&h)) != NULL
--- 107,112 ----
***************
*** 122,127 ****
--- 117,127 ----
  			eprint("uncaught exception: %L\n", e, " ");
  		return 1;
  	}
+ 
+ 	initinput();
+ 	initprims();
+ 	initvars(envp, initial, protected);
+ 	initsignals(allowquit);
  
  	if (loginshell) {
  		char *esrc = str("%L/.esrc", varlookup("home", NULL), "\001");
diff -rc ../orig/parse.y ./parse.y
*** ../orig/parse.y	Thu Oct  1 00:25:37 1992
--- ./parse.y	Wed Oct  7 09:22:03 1992
***************
*** 181,187 ****
  	| words word	{ $$ = cons($2, $1); }
  
  nlwords :		{ $$ = NULL; }
! 	| nlwords '\n'	{ $$ = cons($1, NULL); }
  	| nlwords word	{ $$ = cons($2, $1); }
  
  nl	:
--- 181,187 ----
  	| words word	{ $$ = cons($2, $1); }
  
  nlwords :		{ $$ = NULL; }
! 	| nlwords '\n'	{ $$ = $1; }
  	| nlwords word	{ $$ = cons($2, $1); }
  
  nl	:
***************
*** 257,263 ****
  		default:	panic("redirect: bad redirection kind %d", r->kind);
  		}
  		t = cons(thunkify(t), NULL);
! 		if (r->kind != rHerestring && r->kind != rHeredoc && r->kind != rDup) {
  			Tree *file = r->tree;
  			if (file == NULL)
  				yyerror("null filename in redirection");
--- 257,263 ----
  		default:	panic("redirect: bad redirection kind %d", r->kind);
  		}
  		t = cons(thunkify(t), NULL);
! 		if (r->kind != rHerestring && r->kind != rHeredoc && r->kind != rDup && r->kind != rClose) {
  			Tree *file = r->tree;
  			if (file == NULL)
  				yyerror("null filename in redirection");
diff -rc ../orig/prim-etc.c ./prim-etc.c
*** ../orig/prim-etc.c	Thu Oct  1 00:25:38 1992
--- ./prim-etc.c	Wed Oct  7 09:22:04 1992
***************
*** 113,118 ****
--- 113,129 ----
  	return runstring(str("%L", list, " "));
  }
  
+ PRIM(fork) {
+ 	int pid, status;
+ 	pid = efork(TRUE, FALSE, FALSE);
+ 	if (pid == 0)
+ 		exit(exitstatus(eval(list, NULL, FALSE)));
+ 	status = ewaitfor(pid);
+ 	SIGCHK();
+ 	printstatus(0, status);
+ 	return mklist(mkterm(mkstatus(status), NULL), NULL);
+ }
+ 
  PRIM(dot) {
  	int fd;
  	List *e;
***************
*** 357,361 ****
--- 368,373 ----
  	X(sethistory);
  	X(split);
  	X(fsplit);
+ 	X(fork);
  	return primdict;
  }
diff -rc ../orig/prim-io.c ./prim-io.c
*** ../orig/prim-io.c	Thu Oct  1 00:25:38 1992
--- ./prim-io.c	Wed Oct  7 09:22:04 1992
***************
*** 30,35 ****
--- 30,36 ----
  		int status;
  		RefPop2(str, lp);
  		status = ewaitfor(pid);
+ 		SIGCHK();
  		printstatus(0, status);
  		return mklist(mkterm(mkstatus(status), NULL), NULL);
  	}
diff -rc ../orig/prim.h ./prim.h
*** ../orig/prim.h	Thu Oct  1 00:25:39 1992
--- ./prim.h	Wed Oct  7 09:22:04 1992
***************
*** 1,8 ****
  /* prim.h -- definitions for es primitives */
  
  
! #define	PRIM(name)	static List *prim_##name(List *list, Boolean parent)
! #define	X(name)		(primdict = dictput(primdict, #name, prim_##name))
  
  extern Dict *initprims_controlflow(Dict *primdict);	/* prim-ctl.c */
  extern Dict *initprims_io(Dict *primdict);		/* prim-io.c */
--- 1,8 ----
  /* prim.h -- definitions for es primitives */
  
  
! #define	PRIM(name)	static List *CONCAT(prim_, name)(List *list, Boolean parent)
! #define	X(name)		(primdict = dictput(primdict, STRING(name), CONCAT(prim_, name)))
  
  extern Dict *initprims_controlflow(Dict *primdict);	/* prim-ctl.c */
  extern Dict *initprims_io(Dict *primdict);		/* prim-io.c */
diff -rc ../orig/print.c ./print.c
*** ../orig/print.c	Thu Oct  1 00:25:38 1992
--- ./print.c	Wed Oct  7 09:22:05 1992
***************
*** 283,292 ****
  	format->buf = format->bufbegin;
  	while (n != 0) {
  		int written = write(format->u.n, buf, n);
! 		if (written < 0) {
! 			uerror("write");
! 			exit(1);
! 		}
  		n -= written;
  	}
  }
--- 283,290 ----
  	format->buf = format->bufbegin;
  	while (n != 0) {
  		int written = write(format->u.n, buf, n);
! 		if (written < 0)
! 			return; /* abort silently on write error */
  		n -= written;
  	}
  }
diff -rc ../orig/signal.c ./signal.c
*** ../orig/signal.c	Thu Oct  1 00:25:38 1992
--- ./signal.c	Wed Oct  7 09:22:05 1992
***************
*** 111,123 ****
  extern void setsigdefaults(Boolean background) {
  
  #if JOB_PROTECT && SIGTTOU && SIGTTIN && SIGTSTP
! #define	IGNORE(signal) ((default_ ## signal) = SIG_DFL)
  #else
  #define	IGNORE(signal) \
  	if (!background) \
! 		(default_ ## signal) = SIG_DFL; \
  	else { \
! 		(default_ ## signal) = SIG_IGN; \
  		esignal(sig, SIG_IGN); \
  		/* TODO: remove #signal from $signals */ \
  		break; \
--- 111,123 ----
  extern void setsigdefaults(Boolean background) {
  
  #if JOB_PROTECT && SIGTTOU && SIGTTIN && SIGTSTP
! #define	IGNORE(signal) ((CONCAT(default_, signal)) = SIG_DFL)
  #else
  #define	IGNORE(signal) \
  	if (!background) \
! 		(CONCAT(default_, signal)) = SIG_DFL; \
  	else { \
! 		(CONCAT(default_, signal)) = SIG_IGN; \
  		esignal(sig, SIG_IGN); \
  		/* TODO: remove #signal from $signals */ \
  		break; \
diff -rc ../orig/var.c ./var.c
*** ../orig/var.c	Thu Oct  1 00:25:38 1992
--- ./var.c	Wed Oct  7 09:22:07 1992
***************
*** 13,19 ****
  
  Dict *vars;
  static Vector *env;
! static int envcount, envmin;
  static Tag VarTag;
  static Boolean isdirty;
  static char notexported;
--- 13,19 ----
  
  Dict *vars;
  static Vector *env;
! static int envmin;
  static Tag VarTag;
  static Boolean isdirty;
  static char notexported;
***************
*** 230,256 ****
  }
  
  static void mkenv0(void *dummy, char *key, void *value) {
! 	if (value == NULL || ((Var *) value)->env == &notexported)
  		return;
- 	Ref(Var *, var, value);
  	if (var->env == NULL) {
  		char *envstr = str("%F=%L", key, var->defn, "\001");
  		var->env = envstr;
  	}
! 	assert(envcount < env->len);
! 	env->vector[envcount++] = var->env;
! 	RefEnd(var);
! 	if (envcount == env->len) {
! 		Vector *newenv = mkvector(env->len * 2);
! 		memcpy(&newenv->vector[0], &env->vector[0], envcount * sizeof *env->vector);
  		env = newenv;
  	}
  }
  	
  extern Vector *mkenv(void) {
! 	envcount = envmin;
  	dictforall(vars, mkenv0, NULL);
! 	env->vector[envcount] = NULL;
  	return env;
  }
  
--- 230,259 ----
  }
  
  static void mkenv0(void *dummy, char *key, void *value) {
! 	Var *var = value;
! 	assert(gcblocked > 0);
! 	if (var == NULL || var->env == &notexported)
  		return;
  	if (var->env == NULL) {
  		char *envstr = str("%F=%L", key, var->defn, "\001");
  		var->env = envstr;
  	}
! 	assert(env->count < env->alloclen);
! 	env->vector[env->count++] = var->env;
! 	if (env->count == env->alloclen) {
! 		Vector *newenv = mkvector(env->alloclen * 2);
! 		newenv->count = env->count;
! 		memcpy(newenv->vector, env->vector, env->count * sizeof *env->vector);
  		env = newenv;
  	}
  }
  	
  extern Vector *mkenv(void) {
! 	env->count = envmin;
! 	gcdisable(0);		/* TODO: make this a good guess */
  	dictforall(vars, mkenv0, NULL);
! 	gcenable();
! 	env->vector[env->count] = NULL;
  	return env;
  }
  
***************
*** 328,334 ****
  	globalroot(&env);
  	vars = mkdict();
  	env = mkvector(10);
- 	envcount = 0;
  
  	runstring(initial);
  	initpath();
--- 331,336 ----
***************
*** 338,347 ****
  	for (; (envstr = *envp) != NULL; envp++) {
  		char *eq = strchr(envstr, '=');
  		if (eq == NULL) {
! 			env->vector[envcount++] = envstr;
! 			if (envcount == env->len) {
! 				Vector *newenv = mkvector(env->len * 2);
! 				memcpy(&newenv->vector[0], &env->vector[0], envcount * sizeof (char *));
  				env = newenv;
  			}
  			continue;
--- 340,350 ----
  	for (; (envstr = *envp) != NULL; envp++) {
  		char *eq = strchr(envstr, '=');
  		if (eq == NULL) {
! 			env->vector[env->count++] = envstr;
! 			if (env->count == env->alloclen) {
! 				Vector *newenv = mkvector(env->alloclen * 2);
! 				newenv->count = env->count;
! 				memcpy(newenv->vector, env->vector, env->count * sizeof *env->vector);
  				env = newenv;
  			}
  			continue;
***************
*** 357,363 ****
  		RefEnd(name);
  	}
  
! 	envmin = envcount;
  	printcmds = save_printcmds;
  	noexecute = save_noexecute;
  }
--- 360,366 ----
  		RefEnd(name);
  	}
  
! 	envmin = env->count;
  	printcmds = save_printcmds;
  	noexecute = save_noexecute;
  }
diff -rc ../orig/vec.c ./vec.c
*** ../orig/vec.c	Thu Oct  1 00:25:38 1992
--- ./vec.c	Wed Oct  7 09:22:08 1992
***************
*** 6,32 ****
  static Tag VectorTag;
  
  extern Vector *mkvector(int n) {
- 	int i;
  	Vector *v = gcalloc(offsetof(Vector, vector[n + 1]), &VectorTag);
! 	v->len = n;
! 	for (i = 0; i <= n; i++)
! 		v->vector[i] = NULL;
  	return v;
  }
  
  static void *VectorCopy(void *ov) {
! 	size_t n = offsetof(Vector, vector[((Vector *) ov)->len + 1]);
  	void *nv = gcalloc(n, &VectorTag);
! 	memcpy(nv, ov, sizeof (Vector));
  	return nv;
  }
  
  static size_t VectorScan(void *p) {
  	Vector *v = p;
! 	int i, n = v->len;
  	for (i = 0; i <= n; i++)
  		v->vector[i] = forward(v->vector[i]);
! 	return offsetof(Vector, vector[n + 1]);
  }
  
  static DefineTag(Vector);
--- 6,32 ----
  static Tag VectorTag;
  
  extern Vector *mkvector(int n) {
  	Vector *v = gcalloc(offsetof(Vector, vector[n + 1]), &VectorTag);
! 	v->alloclen = n;
! 	v->count = 0;
! 	/* int i; for (i = 0; i <= n; i++)
! 		v->vector[i] = NULL; */
  	return v;
  }
  
  static void *VectorCopy(void *ov) {
! 	size_t n = offsetof(Vector, vector[((Vector *) ov)->alloclen + 1]);
  	void *nv = gcalloc(n, &VectorTag);
! 	memcpy(nv, ov, n);
  	return nv;
  }
  
  static size_t VectorScan(void *p) {
  	Vector *v = p;
! 	int i, n = v->count;
  	for (i = 0; i <= n; i++)
  		v->vector[i] = forward(v->vector[i]);
! 	return offsetof(Vector, vector[v->alloclen + 1]);
  }
  
  static DefineTag(Vector);
***************
*** 38,43 ****
--- 38,44 ----
  	Ref(Vector *, v, NULL);
  	Ref(List *, lp, list);
  	v = mkvector(n);
+ 	v->count = n;
  
  	for (i = 0; lp != NULL; lp = lp->next, i++) {
  		char *s = getstr(lp->term); /* must evaluate before v->vector[i] */
diff -rc ../orig/version.c ./version.c
*** ../orig/version.c	Thu Oct  1 00:25:38 1992
--- ./version.c	Wed Oct  7 09:22:08 1992
***************
*** 1,2 ****
! static const char id[] = "@(#)es version 0.67: 30 Sep 1992";
  const char * const version = &id[sizeof "@(#)" - 1];
--- 1,2 ----
! static const char id[] = "@(#)es version 0.68: 1 Oct 1992";
  const char * const version = &id[sizeof "@(#)" - 1];