add busybox patch to revert the broken 1.15.2 ash fixes
authorDavide Cavalca <davide@geexbox.org>
Wed, 25 Nov 2009 15:01:49 +0100
changeset 715878663e485688
parent 7157 00c6df9da9e3
child 7159 67209316c07d
add busybox patch to revert the broken 1.15.2 ash fixes
packages/busybox/patches/40_revert-broken-ash-fixes.diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/packages/busybox/patches/40_revert-broken-ash-fixes.diff	Wed Nov 25 15:01:49 2009 +0100
     1.3 @@ -0,0 +1,1060 @@
     1.4 +diff -Naur busybox-1.15.2/shell/ash.c busybox-1.15.2a/shell/ash.c
     1.5 +--- busybox-1.15.2/shell/ash.c	2009-10-08 03:18:15.000000000 +0200
     1.6 ++++ busybox-1.15.2a/shell/ash.c	2009-11-25 14:56:47.000000000 +0100
     1.7 +@@ -112,7 +112,7 @@
     1.8 + 
     1.9 + static const char homestr[] ALIGN1 = "HOME";
    1.10 + static const char snlfmt[] ALIGN1 = "%s\n";
    1.11 +-static const char msg_illnum[] ALIGN1 = "Illegal number: %s";
    1.12 ++static const char illnum[] ALIGN1 = "Illegal number: %s";
    1.13 + 
    1.14 + /*
    1.15 +  * We enclose jmp_buf in a structure so that we can declare pointers to
    1.16 +@@ -142,10 +142,17 @@
    1.17 + 
    1.18 + 	struct jmploc *exception_handler;
    1.19 + 
    1.20 +-	volatile int suppress_int; /* counter */
    1.21 +-	volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
    1.22 ++// disabled by vda: cannot understand how it was supposed to work -
    1.23 ++// cannot fix bugs. That's why you have to explain your non-trivial designs!
    1.24 ++//	/* do we generate EXSIG events */
    1.25 ++//	int exsig; /* counter */
    1.26 ++	volatile int suppressint; /* counter */
    1.27 ++// TODO: rename
    1.28 ++// pendingsig -> pending_sig
    1.29 ++// intpending -> pending_int
    1.30 ++	volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
    1.31 + 	/* last pending signal */
    1.32 +-	volatile /*sig_atomic_t*/ smallint pending_sig;
    1.33 ++	volatile /*sig_atomic_t*/ smallint pendingsig;
    1.34 + 	smallint exception_type; /* kind of exception (0..5) */
    1.35 + 	/* exceptions */
    1.36 + #define EXINT 0         /* SIGINT received */
    1.37 +@@ -193,7 +200,6 @@
    1.38 + 	/* indicates specified signal received */
    1.39 + 	uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
    1.40 + 	char *trap[NSIG];
    1.41 +-	char **trap_ptr;        /* used only by "trap hack" */
    1.42 + 
    1.43 + 	/* Rarely referenced stuff */
    1.44 + #if ENABLE_ASH_RANDOM_SUPPORT
    1.45 +@@ -214,16 +220,16 @@
    1.46 + #define arg0        (G_misc.arg0       )
    1.47 + #define exception_handler (G_misc.exception_handler)
    1.48 + #define exception_type    (G_misc.exception_type   )
    1.49 +-#define suppress_int      (G_misc.suppress_int     )
    1.50 +-#define pending_int       (G_misc.pending_int      )
    1.51 +-#define pending_sig       (G_misc.pending_sig      )
    1.52 ++#define suppressint       (G_misc.suppressint      )
    1.53 ++#define intpending        (G_misc.intpending       )
    1.54 ++//#define exsig             (G_misc.exsig            )
    1.55 ++#define pendingsig        (G_misc.pendingsig       )
    1.56 + #define isloginsh   (G_misc.isloginsh  )
    1.57 + #define nullstr     (G_misc.nullstr    )
    1.58 + #define optlist     (G_misc.optlist    )
    1.59 + #define sigmode     (G_misc.sigmode    )
    1.60 + #define gotsig      (G_misc.gotsig     )
    1.61 + #define trap        (G_misc.trap       )
    1.62 +-#define trap_ptr    (G_misc.trap_ptr   )
    1.63 + #define random_galois_LFSR (G_misc.random_galois_LFSR)
    1.64 + #define random_LCG         (G_misc.random_LCG        )
    1.65 + #define backgndpid  (G_misc.backgndpid )
    1.66 +@@ -233,7 +239,6 @@
    1.67 + 	barrier(); \
    1.68 + 	curdir = nullstr; \
    1.69 + 	physdir = nullstr; \
    1.70 +-	trap_ptr = trap; \
    1.71 + } while (0)
    1.72 + 
    1.73 + 
    1.74 +@@ -278,7 +283,7 @@
    1.75 +  * more fun than worrying about efficiency and portability. :-))
    1.76 +  */
    1.77 + #define INT_OFF do { \
    1.78 +-	suppress_int++; \
    1.79 ++	suppressint++; \
    1.80 + 	xbarrier(); \
    1.81 + } while (0)
    1.82 + 
    1.83 +@@ -319,11 +324,11 @@
    1.84 + {
    1.85 + 	int ex_type;
    1.86 + 
    1.87 +-	pending_int = 0;
    1.88 ++	intpending = 0;
    1.89 + 	/* Signal is not automatically unmasked after it is raised,
    1.90 + 	 * do it ourself - unmask all signals */
    1.91 + 	sigprocmask_allsigs(SIG_UNBLOCK);
    1.92 +-	/* pending_sig = 0; - now done in onsig() */
    1.93 ++	/* pendingsig = 0; - now done in onsig() */
    1.94 + 
    1.95 + 	ex_type = EXSIG;
    1.96 + 	if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
    1.97 +@@ -348,7 +353,7 @@
    1.98 + int_on(void)
    1.99 + {
   1.100 + 	xbarrier();
   1.101 +-	if (--suppress_int == 0 && pending_int) {
   1.102 ++	if (--suppressint == 0 && intpending) {
   1.103 + 		raise_interrupt();
   1.104 + 	}
   1.105 + }
   1.106 +@@ -357,18 +362,18 @@
   1.107 + force_int_on(void)
   1.108 + {
   1.109 + 	xbarrier();
   1.110 +-	suppress_int = 0;
   1.111 +-	if (pending_int)
   1.112 ++	suppressint = 0;
   1.113 ++	if (intpending)
   1.114 + 		raise_interrupt();
   1.115 + }
   1.116 + #define FORCE_INT_ON force_int_on()
   1.117 + 
   1.118 +-#define SAVE_INT(v) ((v) = suppress_int)
   1.119 ++#define SAVE_INT(v) ((v) = suppressint)
   1.120 + 
   1.121 + #define RESTORE_INT(v) do { \
   1.122 + 	xbarrier(); \
   1.123 +-	suppress_int = (v); \
   1.124 +-	if (suppress_int == 0 && pending_int) \
   1.125 ++	suppressint = (v); \
   1.126 ++	if (suppressint == 0 && intpending) \
   1.127 + 		raise_interrupt(); \
   1.128 + } while (0)
   1.129 + 
   1.130 +@@ -456,15 +461,15 @@
   1.131 + /* ============ Parser structures */
   1.132 + 
   1.133 + /* control characters in argument strings */
   1.134 +-#define CTLESC       ((unsigned char)'\201')    /* escape next character */
   1.135 +-#define CTLVAR       ((unsigned char)'\202')    /* variable defn */
   1.136 +-#define CTLENDVAR    ((unsigned char)'\203')
   1.137 +-#define CTLBACKQ     ((unsigned char)'\204')
   1.138 ++#define CTLESC '\201'           /* escape next character */
   1.139 ++#define CTLVAR '\202'           /* variable defn */
   1.140 ++#define CTLENDVAR '\203'
   1.141 ++#define CTLBACKQ '\204'
   1.142 + #define CTLQUOTE 01             /* ored with CTLBACKQ code if in quotes */
   1.143 + /*      CTLBACKQ | CTLQUOTE == '\205' */
   1.144 +-#define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
   1.145 +-#define CTLENDARI    ((unsigned char)'\207')
   1.146 +-#define CTLQUOTEMARK ((unsigned char)'\210')
   1.147 ++#define CTLARI  '\206'          /* arithmetic expression */
   1.148 ++#define CTLENDARI '\207'
   1.149 ++#define CTLQUOTEMARK '\210'
   1.150 + 
   1.151 + /* variable substitution byte (follows CTLVAR) */
   1.152 + #define VSTYPE  0x0f            /* type of variable substitution */
   1.153 +@@ -680,7 +685,7 @@
   1.154 + 	if (DEBUG_PID)
   1.155 + 		fprintf(tracefile, "[%u] ", (int) getpid());
   1.156 + 	if (DEBUG_SIG)
   1.157 +-		fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
   1.158 ++		fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
   1.159 + 	va_start(va, fmt);
   1.160 + 	vfprintf(tracefile, fmt, va);
   1.161 + 	va_end(va);
   1.162 +@@ -696,7 +701,7 @@
   1.163 + 	if (DEBUG_PID)
   1.164 + 		fprintf(tracefile, "[%u] ", (int) getpid());
   1.165 + 	if (DEBUG_SIG)
   1.166 +-		fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
   1.167 ++		fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pendingsig, intpending, suppressint);
   1.168 + 	vfprintf(tracefile, fmt, va);
   1.169 + }
   1.170 + 
   1.171 +@@ -1551,7 +1556,7 @@
   1.172 + number(const char *s)
   1.173 + {
   1.174 + 	if (!is_number(s))
   1.175 +-		ash_msg_and_raise_error(msg_illnum, s);
   1.176 ++		ash_msg_and_raise_error(illnum, s);
   1.177 + 	return atoi(s);
   1.178 + }
   1.179 + 
   1.180 +@@ -2346,6 +2351,8 @@
   1.181 + #define CD_PHYSICAL 1
   1.182 + #define CD_PRINT 2
   1.183 + 
   1.184 ++static int docd(const char *, int);
   1.185 ++
   1.186 + static int
   1.187 + cdopt(void)
   1.188 + {
   1.189 +@@ -2353,7 +2360,7 @@
   1.190 + 	int i, j;
   1.191 + 
   1.192 + 	j = 'L';
   1.193 +-	while ((i = nextopt("LP")) != '\0') {
   1.194 ++	while ((i = nextopt("LP"))) {
   1.195 + 		if (i != j) {
   1.196 + 			flags ^= CD_PHYSICAL;
   1.197 + 			j = i;
   1.198 +@@ -2703,8 +2710,8 @@
   1.199 + 	} else
   1.200 + #endif
   1.201 + 	{
   1.202 +-		if ((unsigned char)c >= CTLESC
   1.203 +-		 && (unsigned char)c <= CTLQUOTEMARK
   1.204 ++		if ((unsigned char)c >= (unsigned char)(CTLESC)
   1.205 ++		 && (unsigned char)c <= (unsigned char)(CTLQUOTEMARK)
   1.206 + 		) {
   1.207 + 			return CCTL;
   1.208 + 		}
   1.209 +@@ -3233,9 +3240,9 @@
   1.210 + #define FORK_NOJOB 2
   1.211 + 
   1.212 + /* mode flags for showjob(s) */
   1.213 +-#define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
   1.214 +-#define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
   1.215 +-#define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
   1.216 ++#define SHOW_PGID       0x01    /* only show pgid - for jobs -p */
   1.217 ++#define SHOW_PID        0x04    /* include process pid */
   1.218 ++#define SHOW_CHANGED    0x08    /* only jobs whose state has changed */
   1.219 + 
   1.220 + /*
   1.221 +  * A job structure contains information about a job.  A job is either a
   1.222 +@@ -3243,6 +3250,7 @@
   1.223 +  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
   1.224 +  * array of pids.
   1.225 +  */
   1.226 ++
   1.227 + struct procstat {
   1.228 + 	pid_t   pid;            /* process id */
   1.229 + 	int     status;         /* last process status from wait() */
   1.230 +@@ -3305,14 +3313,14 @@
   1.231 + {
   1.232 + 	gotsig[signo - 1] = 1;
   1.233 + 
   1.234 +-	if (signo == SIGINT && !trap[SIGINT]) {
   1.235 +-		if (!suppress_int) {
   1.236 +-			pending_sig = 0;
   1.237 ++	if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
   1.238 ++		if (!suppressint) {
   1.239 ++			pendingsig = 0;
   1.240 + 			raise_interrupt(); /* does not return */
   1.241 + 		}
   1.242 +-		pending_int = 1;
   1.243 ++		intpending = 1;
   1.244 + 	} else {
   1.245 +-		pending_sig = signo;
   1.246 ++		pendingsig = signo;
   1.247 + 	}
   1.248 + }
   1.249 + 
   1.250 +@@ -3535,6 +3543,7 @@
   1.251 + 	}
   1.252 + 
   1.253 + 	if (is_number(p)) {
   1.254 ++// TODO: number() instead? It does error checking...
   1.255 + 		num = atoi(p);
   1.256 + 		if (num < njobs) {
   1.257 + 			jp = jobtab + num - 1;
   1.258 +@@ -3906,7 +3915,7 @@
   1.259 + blocking_wait_with_raise_on_sig(struct job *job)
   1.260 + {
   1.261 + 	pid_t pid = dowait(DOWAIT_BLOCK, job);
   1.262 +-	if (pid <= 0 && pending_sig)
   1.263 ++	if (pid <= 0 && pendingsig)
   1.264 + 		raise_exception(EXSIG);
   1.265 + 	return pid;
   1.266 + }
   1.267 +@@ -3923,7 +3932,7 @@
   1.268 + 
   1.269 + 	ps = jp->ps;
   1.270 + 
   1.271 +-	if (mode & SHOW_ONLY_PGID) { /* jobs -p */
   1.272 ++	if (mode & SHOW_PGID) {
   1.273 + 		/* just output process (group) id of pipeline */
   1.274 + 		fprintf(out, "%d\n", ps->pid);
   1.275 + 		return;
   1.276 +@@ -3933,11 +3942,11 @@
   1.277 + 	indent_col = col;
   1.278 + 
   1.279 + 	if (jp == curjob)
   1.280 +-		s[col - 3] = '+';
   1.281 ++		s[col - 2] = '+';
   1.282 + 	else if (curjob && jp == curjob->prev_job)
   1.283 +-		s[col - 3] = '-';
   1.284 ++		s[col - 2] = '-';
   1.285 + 
   1.286 +-	if (mode & SHOW_PIDS)
   1.287 ++	if (mode & SHOW_PID)
   1.288 + 		col += fmtstr(s + col, 16, "%d ", ps->pid);
   1.289 + 
   1.290 + 	psend = ps + jp->nprocs;
   1.291 +@@ -3951,32 +3960,25 @@
   1.292 + 			status = jp->stopstatus;
   1.293 + 		col += sprint_status(s + col, status, 0);
   1.294 + 	}
   1.295 +-	/* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
   1.296 + 
   1.297 +-	/* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
   1.298 +-	 * or prints several "PID             | <cmdN>" lines,
   1.299 +-	 * depending on SHOW_PIDS bit.
   1.300 +-	 * We do not print status of individual processes
   1.301 +-	 * between PID and <cmdN>. bash does it, but not very well:
   1.302 +-	 * first line shows overall job status, not process status,
   1.303 +-	 * making it impossible to know 1st process status.
   1.304 +-	 */
   1.305 + 	goto start;
   1.306 +-	while (1) {
   1.307 ++
   1.308 ++	do {
   1.309 + 		/* for each process */
   1.310 +-		s[0] = '\0';
   1.311 +-		col = 33;
   1.312 +-		if (mode & SHOW_PIDS)
   1.313 +-			col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->pid) - 1;
   1.314 ++		col = fmtstr(s, 48, " |\n%*c%d ", indent_col, ' ', ps->pid) - 3;
   1.315 +  start:
   1.316 +-		fprintf(out, "%s%*c", s, 33 - col >= 0 ? 33 - col : 0, ' ');
   1.317 +-		if (ps != jp->ps)
   1.318 +-			fprintf(out, "| ");
   1.319 +-		fprintf(out, "%s", ps->cmd);
   1.320 +-		if (++ps == psend)
   1.321 ++		fprintf(out, "%s%*c%s",
   1.322 ++			s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
   1.323 ++		);
   1.324 ++		if (!(mode & SHOW_PID)) {
   1.325 ++			showpipe(jp, out);
   1.326 + 			break;
   1.327 +-	}
   1.328 +-	outcslow('\n', out);
   1.329 ++		}
   1.330 ++		if (++ps == psend) {
   1.331 ++			outcslow('\n', out);
   1.332 ++			break;
   1.333 ++		}
   1.334 ++	} while (1);
   1.335 + 
   1.336 + 	jp->changed = 0;
   1.337 + 
   1.338 +@@ -4014,17 +4016,17 @@
   1.339 + 	int mode, m;
   1.340 + 
   1.341 + 	mode = 0;
   1.342 +-	while ((m = nextopt("lp")) != '\0') {
   1.343 ++	while ((m = nextopt("lp"))) {
   1.344 + 		if (m == 'l')
   1.345 +-			mode |= SHOW_PIDS;
   1.346 ++			mode = SHOW_PID;
   1.347 + 		else
   1.348 +-			mode |= SHOW_ONLY_PGID;
   1.349 ++			mode = SHOW_PGID;
   1.350 + 	}
   1.351 + 
   1.352 + 	argv = argptr;
   1.353 + 	if (*argv) {
   1.354 + 		do
   1.355 +-			showjob(stdout, getjob(*argv, 0), mode);
   1.356 ++			showjob(stdout, getjob(*argv,0), mode);
   1.357 + 		while (*++argv);
   1.358 + 	} else
   1.359 + 		showjobs(stdout, mode);
   1.360 +@@ -4068,7 +4070,9 @@
   1.361 + 	int retval;
   1.362 + 	struct job *jp;
   1.363 + 
   1.364 +-	if (pending_sig)
   1.365 ++//	exsig++;
   1.366 ++//	xbarrier();
   1.367 ++	if (pendingsig)
   1.368 + 		raise_exception(EXSIG);
   1.369 + 
   1.370 + 	nextopt(nullstr);
   1.371 +@@ -4304,7 +4308,7 @@
   1.372 + 		if (!str)
   1.373 + 			continue;
   1.374 +  dostr:
   1.375 +-		while ((c = *str++) != '\0') {
   1.376 ++		while ((c = *str++)) {
   1.377 + 			USTPUTC(c, nextc);
   1.378 + 		}
   1.379 + 	}
   1.380 +@@ -4523,11 +4527,9 @@
   1.381 + 	for (tp = trap; tp < &trap[NSIG]; tp++) {
   1.382 + 		if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
   1.383 + 			INT_OFF;
   1.384 +-			if (trap_ptr == trap)
   1.385 +-				free(*tp);
   1.386 +-			/* else: it "belongs" to trap_ptr vector, don't free */
   1.387 ++			free(*tp);
   1.388 + 			*tp = NULL;
   1.389 +-			if ((tp - trap) != 0)
   1.390 ++			if (tp != &trap[0])
   1.391 + 				setsignal(tp - trap);
   1.392 + 			INT_ON;
   1.393 + 		}
   1.394 +@@ -4552,53 +4554,6 @@
   1.395 + 	 * Do we do it correctly? */
   1.396 + 
   1.397 + 	closescript();
   1.398 +-
   1.399 +-	if (mode == FORK_NOJOB          /* is it `xxx` ? */
   1.400 +-	 && n && n->type == NCMD        /* is it single cmd? */
   1.401 +-	/* && n->ncmd.args->type == NARG - always true? */
   1.402 +-	 && strcmp(n->ncmd.args->narg.text, "trap") == 0
   1.403 +-	 && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
   1.404 +-	/* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
   1.405 +-	) {
   1.406 +-		TRACE(("Trap hack\n"));
   1.407 +-		/* Awful hack for `trap` or $(trap).
   1.408 +-		 *
   1.409 +-		 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
   1.410 +-		 * contains an example where "trap" is executed in a subshell:
   1.411 +-		 *
   1.412 +-		 * save_traps=$(trap)
   1.413 +-		 * ...
   1.414 +-		 * eval "$save_traps"
   1.415 +-		 *
   1.416 +-		 * Standard does not say that "trap" in subshell shall print
   1.417 +-		 * parent shell's traps. It only says that its output
   1.418 +-		 * must have suitable form, but then, in the above example
   1.419 +-		 * (which is not supposed to be normative), it implies that.
   1.420 +-		 *
   1.421 +-		 * bash (and probably other shell) does implement it
   1.422 +-		 * (traps are reset to defaults, but "trap" still shows them),
   1.423 +-		 * but as a result, "trap" logic is hopelessly messed up:
   1.424 +-		 *
   1.425 +-		 * # trap
   1.426 +-		 * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
   1.427 +-		 * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
   1.428 +-		 * # true | trap   <--- trap is in subshell - no output (ditto)
   1.429 +-		 * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
   1.430 +-		 * trap -- 'echo Ho' SIGWINCH
   1.431 +-		 * # echo `(trap)`         <--- in subshell in subshell - output
   1.432 +-		 * trap -- 'echo Ho' SIGWINCH
   1.433 +-		 * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
   1.434 +-		 * trap -- 'echo Ho' SIGWINCH
   1.435 +-		 *
   1.436 +-		 * The rules when to forget and when to not forget traps
   1.437 +-		 * get really complex and nonsensical.
   1.438 +-		 *
   1.439 +-		 * Our solution: ONLY bare $(trap) or `trap` is special.
   1.440 +-		 */
   1.441 +-		/* Save trap handler strings for trap builtin to print */
   1.442 +-		trap_ptr = memcpy(xmalloc(sizeof(trap)), trap, sizeof(trap));
   1.443 +-		/* Fall through into clearing traps */
   1.444 +-	}
   1.445 + 	clear_traps();
   1.446 + #if JOBS
   1.447 + 	/* do job control only in root shell */
   1.448 +@@ -4643,14 +4598,8 @@
   1.449 + 		setsignal(SIGQUIT);
   1.450 + 	}
   1.451 + #if JOBS
   1.452 +-	if (n && n->type == NCMD
   1.453 +-	 && strcmp(n->ncmd.args->narg.text, "jobs") == 0
   1.454 +-	) {
   1.455 ++	if (n && n->type == NCMD && strcmp(n->ncmd.args->narg.text, "jobs") == 0) {
   1.456 + 		TRACE(("Job hack\n"));
   1.457 +-		/* "jobs": we do not want to clear job list for it,
   1.458 +-		 * instead we remove only _its_ own_ job from job list.
   1.459 +-		 * This makes "jobs .... | cat" more useful.
   1.460 +-		 */
   1.461 + 		freejob(curjob);
   1.462 + 		return;
   1.463 + 	}
   1.464 +@@ -5043,7 +4992,7 @@
   1.465 + 	struct redirtab *next;
   1.466 + 	int nullredirs;
   1.467 + 	int pair_count;
   1.468 +-	struct two_fd_t two_fd[];
   1.469 ++	struct two_fd_t two_fd[0];
   1.470 + };
   1.471 + #define redirlist (G_var.redirlist)
   1.472 + 
   1.473 +@@ -5354,7 +5303,7 @@
   1.474 + #define EXP_WORD        0x80    /* expand word in parameter expansion */
   1.475 + #define EXP_QWORD       0x100   /* expand word in quoted parameter expansion */
   1.476 + /*
   1.477 +- * rmescape() flags
   1.478 ++ * _rmescape() flags
   1.479 +  */
   1.480 + #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
   1.481 + #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
   1.482 +@@ -5408,7 +5357,7 @@
   1.483 + {
   1.484 + 	size_t esc = 0;
   1.485 + 
   1.486 +-	while (p > start && (unsigned char)*--p == CTLESC) {
   1.487 ++	while (p > start && *--p == CTLESC) {
   1.488 + 		esc++;
   1.489 + 	}
   1.490 + 	return esc;
   1.491 +@@ -5418,19 +5367,19 @@
   1.492 +  * Remove any CTLESC characters from a string.
   1.493 +  */
   1.494 + static char *
   1.495 +-rmescapes(char *str, int flag)
   1.496 ++_rmescapes(char *str, int flag)
   1.497 + {
   1.498 + 	static const char qchars[] ALIGN1 = { CTLESC, CTLQUOTEMARK, '\0' };
   1.499 + 
   1.500 + 	char *p, *q, *r;
   1.501 + 	unsigned inquotes;
   1.502 +-	unsigned protect_against_glob;
   1.503 +-	unsigned globbing;
   1.504 ++	int notescaped;
   1.505 ++	int globbing;
   1.506 + 
   1.507 + 	p = strpbrk(str, qchars);
   1.508 +-	if (!p)
   1.509 ++	if (!p) {
   1.510 + 		return str;
   1.511 +-
   1.512 ++	}
   1.513 + 	q = p;
   1.514 + 	r = str;
   1.515 + 	if (flag & RMESCAPE_ALLOC) {
   1.516 +@@ -5449,33 +5398,28 @@
   1.517 + 			q = (char *)memcpy(q, str, len) + len;
   1.518 + 		}
   1.519 + 	}
   1.520 +-
   1.521 + 	inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
   1.522 + 	globbing = flag & RMESCAPE_GLOB;
   1.523 +-	protect_against_glob = globbing;
   1.524 ++	notescaped = globbing;
   1.525 + 	while (*p) {
   1.526 + 		if (*p == CTLQUOTEMARK) {
   1.527 +-// TODO: if no RMESCAPE_QUOTED in flags, inquotes never becomes 0
   1.528 +-// (alternates between RMESCAPE_QUOTED and ~RMESCAPE_QUOTED). Is it ok?
   1.529 +-// Note: both inquotes and protect_against_glob only affect whether
   1.530 +-// CTLESC,<ch> gets converted to <ch> or to \<ch>
   1.531 + 			inquotes = ~inquotes;
   1.532 + 			p++;
   1.533 +-			protect_against_glob = globbing;
   1.534 ++			notescaped = globbing;
   1.535 + 			continue;
   1.536 + 		}
   1.537 + 		if (*p == '\\') {
   1.538 + 			/* naked back slash */
   1.539 +-			protect_against_glob = 0;
   1.540 ++			notescaped = 0;
   1.541 + 			goto copy;
   1.542 + 		}
   1.543 + 		if (*p == CTLESC) {
   1.544 + 			p++;
   1.545 +-			if (protect_against_glob && inquotes && *p != '/') {
   1.546 ++			if (notescaped && inquotes && *p != '/') {
   1.547 + 				*q++ = '\\';
   1.548 + 			}
   1.549 + 		}
   1.550 +-		protect_against_glob = globbing;
   1.551 ++		notescaped = globbing;
   1.552 +  copy:
   1.553 + 		*q++ = *p++;
   1.554 + 	}
   1.555 +@@ -5486,6 +5430,8 @@
   1.556 + 	}
   1.557 + 	return r;
   1.558 + }
   1.559 ++#define rmescapes(p) _rmescapes((p), 0)
   1.560 ++
   1.561 + #define pmatch(a, b) !fnmatch((a), (b), 0)
   1.562 + 
   1.563 + /*
   1.564 +@@ -5500,7 +5446,7 @@
   1.565 + 	if (quoted) {
   1.566 + 		flag |= RMESCAPE_QUOTED;
   1.567 + 	}
   1.568 +-	return rmescapes((char *)pattern, flag);
   1.569 ++	return _rmescapes((char *)pattern, flag);
   1.570 + }
   1.571 + 
   1.572 + /*
   1.573 +@@ -5511,17 +5457,14 @@
   1.574 + {
   1.575 + 	char *q = expdest;
   1.576 + 
   1.577 +-	q = makestrspace(quotes ? len * 2 : len, q);
   1.578 ++	q = makestrspace(len * 2, q);
   1.579 + 
   1.580 + 	while (len--) {
   1.581 + 		int c = signed_char2int(*p++);
   1.582 + 		if (!c)
   1.583 + 			continue;
   1.584 +-		if (quotes) {
   1.585 +-			int n = SIT(c, syntax);
   1.586 +-			if (n == CCTL || n == CBACK)
   1.587 +-				USTPUTC(CTLESC, q);
   1.588 +-		}
   1.589 ++		if (quotes && (SIT(c, syntax) == CCTL || SIT(c, syntax) == CBACK))
   1.590 ++			USTPUTC(CTLESC, q);
   1.591 + 		USTPUTC(c, q);
   1.592 + 	}
   1.593 + 
   1.594 +@@ -5598,13 +5541,13 @@
   1.595 + }
   1.596 + 
   1.597 + static char *
   1.598 +-exptilde(char *startp, char *p, int flags)
   1.599 ++exptilde(char *startp, char *p, int flag)
   1.600 + {
   1.601 + 	char c;
   1.602 + 	char *name;
   1.603 + 	struct passwd *pw;
   1.604 + 	const char *home;
   1.605 +-	int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR);
   1.606 ++	int quotes = flag & (EXP_FULL | EXP_CASE);
   1.607 + 	int startloc;
   1.608 + 
   1.609 + 	name = p + 1;
   1.610 +@@ -5616,7 +5559,7 @@
   1.611 + 		case CTLQUOTEMARK:
   1.612 + 			return startp;
   1.613 + 		case ':':
   1.614 +-			if (flags & EXP_VARTILDE)
   1.615 ++			if (flag & EXP_VARTILDE)
   1.616 + 				goto done;
   1.617 + 			break;
   1.618 + 		case '/':
   1.619 +@@ -5821,7 +5764,7 @@
   1.620 + 	expdest = p;
   1.621 + 
   1.622 + 	if (quotes)
   1.623 +-		rmescapes(p + 2, 0);
   1.624 ++		rmescapes(p + 2);
   1.625 + 
   1.626 + 	len = cvtnum(ash_arith(p + 2));
   1.627 + 
   1.628 +@@ -5831,7 +5774,7 @@
   1.629 + #endif
   1.630 + 
   1.631 + /* argstr needs it */
   1.632 +-static char *evalvar(char *p, int flags, struct strlist *var_str_list);
   1.633 ++static char *evalvar(char *p, int flag, struct strlist *var_str_list);
   1.634 + 
   1.635 + /*
   1.636 +  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
   1.637 +@@ -5843,7 +5786,7 @@
   1.638 +  * for correct expansion of "B=$A" word.
   1.639 +  */
   1.640 + static void
   1.641 +-argstr(char *p, int flags, struct strlist *var_str_list)
   1.642 ++argstr(char *p, int flag, struct strlist *var_str_list)
   1.643 + {
   1.644 + 	static const char spclchars[] ALIGN1 = {
   1.645 + 		'=',
   1.646 +@@ -5861,44 +5804,42 @@
   1.647 + 	};
   1.648 + 	const char *reject = spclchars;
   1.649 + 	int c;
   1.650 +-	int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
   1.651 +-	int breakall = flags & EXP_WORD;
   1.652 ++	int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
   1.653 ++	int breakall = flag & EXP_WORD;
   1.654 + 	int inquotes;
   1.655 + 	size_t length;
   1.656 + 	int startloc;
   1.657 + 
   1.658 +-	if (!(flags & EXP_VARTILDE)) {
   1.659 ++	if (!(flag & EXP_VARTILDE)) {
   1.660 + 		reject += 2;
   1.661 +-	} else if (flags & EXP_VARTILDE2) {
   1.662 ++	} else if (flag & EXP_VARTILDE2) {
   1.663 + 		reject++;
   1.664 + 	}
   1.665 + 	inquotes = 0;
   1.666 + 	length = 0;
   1.667 +-	if (flags & EXP_TILDE) {
   1.668 ++	if (flag & EXP_TILDE) {
   1.669 + 		char *q;
   1.670 + 
   1.671 +-		flags &= ~EXP_TILDE;
   1.672 ++		flag &= ~EXP_TILDE;
   1.673 +  tilde:
   1.674 + 		q = p;
   1.675 +-		if (*q == CTLESC && (flags & EXP_QWORD))
   1.676 ++		if (*q == CTLESC && (flag & EXP_QWORD))
   1.677 + 			q++;
   1.678 + 		if (*q == '~')
   1.679 +-			p = exptilde(p, q, flags);
   1.680 ++			p = exptilde(p, q, flag);
   1.681 + 	}
   1.682 +  start:
   1.683 + 	startloc = expdest - (char *)stackblock();
   1.684 + 	for (;;) {
   1.685 + 		length += strcspn(p + length, reject);
   1.686 +-		c = (unsigned char) p[length];
   1.687 +-		if (c) {
   1.688 +-			if (!(c & 0x80)
   1.689 ++		c = p[length];
   1.690 ++		if (c && (!(c & 0x80)
   1.691 + #if ENABLE_SH_MATH_SUPPORT
   1.692 +-			 || c == CTLENDARI
   1.693 ++					|| c == CTLENDARI
   1.694 + #endif
   1.695 +-			) {
   1.696 +-				/* c == '=' || c == ':' || c == CTLENDARI */
   1.697 +-				length++;
   1.698 +-			}
   1.699 ++		   )) {
   1.700 ++			/* c == '=' || c == ':' || c == CTLENDARI */
   1.701 ++			length++;
   1.702 + 		}
   1.703 + 		if (length > 0) {
   1.704 + 			int newloc;
   1.705 +@@ -5916,11 +5857,11 @@
   1.706 + 		case '\0':
   1.707 + 			goto breakloop;
   1.708 + 		case '=':
   1.709 +-			if (flags & EXP_VARTILDE2) {
   1.710 ++			if (flag & EXP_VARTILDE2) {
   1.711 + 				p--;
   1.712 + 				continue;
   1.713 + 			}
   1.714 +-			flags |= EXP_VARTILDE2;
   1.715 ++			flag |= EXP_VARTILDE2;
   1.716 + 			reject++;
   1.717 + 			/* fall through */
   1.718 + 		case ':':
   1.719 +@@ -5939,13 +5880,15 @@
   1.720 + 			goto breakloop;
   1.721 + 		case CTLQUOTEMARK:
   1.722 + 			/* "$@" syntax adherence hack */
   1.723 +-			if (!inquotes
   1.724 +-			 && memcmp(p, dolatstr, 4) == 0
   1.725 +-			 && (  p[4] == CTLQUOTEMARK
   1.726 +-			    || (p[4] == CTLENDVAR && p[5] == CTLQUOTEMARK)
   1.727 +-			    )
   1.728 ++			if (
   1.729 ++				!inquotes &&
   1.730 ++				!memcmp(p, dolatstr, 4) &&
   1.731 ++				(p[4] == CTLQUOTEMARK || (
   1.732 ++					p[4] == CTLENDVAR &&
   1.733 ++					p[5] == CTLQUOTEMARK
   1.734 ++				))
   1.735 + 			) {
   1.736 +-				p = evalvar(p + 1, flags, /* var_str_list: */ NULL) + 1;
   1.737 ++				p = evalvar(p + 1, flag, /* var_str_list: */ NULL) + 1;
   1.738 + 				goto start;
   1.739 + 			}
   1.740 + 			inquotes = !inquotes;
   1.741 +@@ -5961,10 +5904,10 @@
   1.742 + 			length++;
   1.743 + 			goto addquote;
   1.744 + 		case CTLVAR:
   1.745 +-			p = evalvar(p, flags, var_str_list);
   1.746 ++			p = evalvar(p, flag, var_str_list);
   1.747 + 			goto start;
   1.748 + 		case CTLBACKQ:
   1.749 +-			c = '\0';
   1.750 ++			c = 0;
   1.751 + 		case CTLBACKQ|CTLQUOTE:
   1.752 + 			expbackq(argbackq->n, c, quotes);
   1.753 + 			argbackq = argbackq->next;
   1.754 +@@ -6170,15 +6113,15 @@
   1.755 + #if ENABLE_ASH_BASH_COMPAT
   1.756 + 	case VSSUBSTR:
   1.757 + 		loc = str = stackblock() + strloc;
   1.758 +-		/* Read POS in ${var:POS:LEN} */
   1.759 +-		pos = atoi(loc); /* number(loc) errors out on "1:4" */
   1.760 ++// TODO: number() instead? It does error checking...
   1.761 ++		pos = atoi(loc);
   1.762 + 		len = str - startp - 1;
   1.763 + 
   1.764 + 		/* *loc != '\0', guaranteed by parser */
   1.765 + 		if (quotes) {
   1.766 + 			char *ptr;
   1.767 + 
   1.768 +-			/* Adjust the length by the number of escapes */
   1.769 ++			/* We must adjust the length by the number of escapes we find. */
   1.770 + 			for (ptr = startp; ptr < (str - 1); ptr++) {
   1.771 + 				if (*ptr == CTLESC) {
   1.772 + 					len--;
   1.773 +@@ -6189,22 +6132,15 @@
   1.774 + 		orig_len = len;
   1.775 + 
   1.776 + 		if (*loc++ == ':') {
   1.777 +-			/* ${var::LEN} */
   1.778 +-			len = number(loc);
   1.779 ++// TODO: number() instead? It does error checking...
   1.780 ++			len = atoi(loc);
   1.781 + 		} else {
   1.782 +-			/* Skip POS in ${var:POS:LEN} */
   1.783 + 			len = orig_len;
   1.784 +-			while (*loc && *loc != ':') {
   1.785 +-				/* TODO?
   1.786 +-				 * bash complains on: var=qwe; echo ${var:1a:123}
   1.787 +-				if (!isdigit(*loc))
   1.788 +-					ash_msg_and_raise_error(msg_illnum, str);
   1.789 +-				 */
   1.790 ++			while (*loc && *loc != ':')
   1.791 + 				loc++;
   1.792 +-			}
   1.793 +-			if (*loc++ == ':') {
   1.794 +-				len = number(loc);
   1.795 +-			}
   1.796 ++			if (*loc++ == ':')
   1.797 ++// TODO: number() instead? It does error checking...
   1.798 ++				len = atoi(loc);
   1.799 + 		}
   1.800 + 		if (pos >= orig_len) {
   1.801 + 			pos = 0;
   1.802 +@@ -6248,7 +6184,7 @@
   1.803 + 	rmesc = startp;
   1.804 + 	rmescend = (char *)stackblock() + strloc;
   1.805 + 	if (quotes) {
   1.806 +-		rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
   1.807 ++		rmesc = _rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
   1.808 + 		if (rmesc != startp) {
   1.809 + 			rmescend = expdest;
   1.810 + 			startp = (char *)stackblock() + startloc;
   1.811 +@@ -6379,7 +6315,7 @@
   1.812 + 	int syntax;
   1.813 + 	int quoted = varflags & VSQUOTE;
   1.814 + 	int subtype = varflags & VSTYPE;
   1.815 +-	int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR);
   1.816 ++	int quotes = flags & (EXP_FULL | EXP_CASE);
   1.817 + 
   1.818 + 	if (quoted && (flags & EXP_FULL))
   1.819 + 		sep = 1 << CHAR_BIT;
   1.820 +@@ -6423,7 +6359,7 @@
   1.821 + 		ap = shellparam.p;
   1.822 + 		if (!ap)
   1.823 + 			return -1;
   1.824 +-		while ((p = *ap++) != NULL) {
   1.825 ++		while ((p = *ap++)) {
   1.826 + 			size_t partlen;
   1.827 + 
   1.828 + 			partlen = strlen(p);
   1.829 +@@ -6457,7 +6393,8 @@
   1.830 + 	case '7':
   1.831 + 	case '8':
   1.832 + 	case '9':
   1.833 +-		num = atoi(name); /* number(name) fails on ${N#str} etc */
   1.834 ++// TODO: number() instead? It does error checking...
   1.835 ++		num = atoi(name);
   1.836 + 		if (num < 0 || num > shellparam.nparam)
   1.837 + 			return -1;
   1.838 + 		p = num ? shellparam.p[num - 1] : arg0;
   1.839 +@@ -6509,7 +6446,7 @@
   1.840 +  * input string.
   1.841 +  */
   1.842 + static char *
   1.843 +-evalvar(char *p, int flags, struct strlist *var_str_list)
   1.844 ++evalvar(char *p, int flag, struct strlist *var_str_list)
   1.845 + {
   1.846 + 	char varflags;
   1.847 + 	char subtype;
   1.848 +@@ -6520,7 +6457,7 @@
   1.849 + 	int startloc;
   1.850 + 	ssize_t varlen;
   1.851 + 
   1.852 +-	varflags = (unsigned char) *p++;
   1.853 ++	varflags = *p++;
   1.854 + 	subtype = varflags & VSTYPE;
   1.855 + 	quoted = varflags & VSQUOTE;
   1.856 + 	var = p;
   1.857 +@@ -6529,7 +6466,7 @@
   1.858 + 	p = strchr(p, '=') + 1;
   1.859 + 
   1.860 +  again:
   1.861 +-	varlen = varvalue(var, varflags, flags, var_str_list);
   1.862 ++	varlen = varvalue(var, varflags, flag, var_str_list);
   1.863 + 	if (varflags & VSNUL)
   1.864 + 		varlen--;
   1.865 + 
   1.866 +@@ -6542,8 +6479,8 @@
   1.867 +  vsplus:
   1.868 + 		if (varlen < 0) {
   1.869 + 			argstr(
   1.870 +-				p, flags | EXP_TILDE |
   1.871 +-					(quoted ? EXP_QWORD : EXP_WORD),
   1.872 ++				p, flag | EXP_TILDE |
   1.873 ++					(quoted ?  EXP_QWORD : EXP_WORD),
   1.874 + 				var_str_list
   1.875 + 			);
   1.876 + 			goto end;
   1.877 +@@ -6615,8 +6552,7 @@
   1.878 + 		patloc = expdest - (char *)stackblock();
   1.879 + 		if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype,
   1.880 + 				startloc, varflags,
   1.881 +-//TODO: | EXP_REDIR too? All other such places do it too
   1.882 +-				/* quotes: */ flags & (EXP_FULL | EXP_CASE),
   1.883 ++				/* quotes: */ flag & (EXP_FULL | EXP_CASE),
   1.884 + 				var_str_list)
   1.885 + 		) {
   1.886 + 			int amount = expdest - (
   1.887 +@@ -6870,7 +6806,7 @@
   1.888 + 		p++;
   1.889 + 	if (*p == '.')
   1.890 + 		matchdot++;
   1.891 +-	while (!pending_int && (dp = readdir(dirp)) != NULL) {
   1.892 ++	while (!intpending && (dp = readdir(dirp)) != NULL) {
   1.893 + 		if (dp->d_name[0] == '.' && !matchdot)
   1.894 + 			continue;
   1.895 + 		if (pmatch(start, dp->d_name)) {
   1.896 +@@ -6991,7 +6927,7 @@
   1.897 + 			 */
   1.898 +  nometa:
   1.899 + 			*exparg.lastp = str;
   1.900 +-			rmescapes(str->text, 0);
   1.901 ++			rmescapes(str->text);
   1.902 + 			exparg.lastp = &str->next;
   1.903 + 		} else {
   1.904 + 			*exparg.lastp = NULL;
   1.905 +@@ -7039,7 +6975,7 @@
   1.906 + 		expandmeta(exparg.list /*, flag*/);
   1.907 + 	} else {
   1.908 + 		if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
   1.909 +-			rmescapes(p, 0);
   1.910 ++			rmescapes(p);
   1.911 + 		sp = stzalloc(sizeof(*sp));
   1.912 + 		sp->text = p;
   1.913 + 		*exparg.lastp = sp;
   1.914 +@@ -7264,8 +7200,8 @@
   1.915 + 		break;
   1.916 + 	}
   1.917 + 	exitstatus = exerrno;
   1.918 +-	TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
   1.919 +-		argv[0], e, suppress_int));
   1.920 ++	TRACE(("shellexec failed for %s, errno %d, suppressint %d\n",
   1.921 ++		argv[0], e, suppressint));
   1.922 + 	ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found"));
   1.923 + 	/* NOTREACHED */
   1.924 + }
   1.925 +@@ -8067,7 +8003,7 @@
   1.926 + 	uint8_t savestatus;
   1.927 + 
   1.928 + 	savestatus = exitstatus;
   1.929 +-	pending_sig = 0;
   1.930 ++	pendingsig = 0;
   1.931 + 	xbarrier();
   1.932 + 
   1.933 + 	TRACE(("dotrap entered\n"));
   1.934 +@@ -8247,7 +8183,7 @@
   1.935 +  out1:
   1.936 + 	if (checkexit & exitstatus)
   1.937 + 		evalskip |= SKIPEVAL;
   1.938 +-	else if (pending_sig && dotrap())
   1.939 ++	else if (pendingsig && dotrap())
   1.940 + 		goto exexit;
   1.941 + 
   1.942 + 	if (flags & EV_EXIT) {
   1.943 +@@ -9167,7 +9103,7 @@
   1.944 + 			if (i == EXINT)
   1.945 + 				exit_status = 128 + SIGINT;
   1.946 + 			if (i == EXSIG)
   1.947 +-				exit_status = 128 + pending_sig;
   1.948 ++				exit_status = 128 + pendingsig;
   1.949 + 			exitstatus = exit_status;
   1.950 + 			if (i == EXINT || spclbltin > 0) {
   1.951 +  raise:
   1.952 +@@ -9221,6 +9157,7 @@
   1.953 + 	exitstatus |= ferror(stdout);
   1.954 + 	clearerr(stdout);
   1.955 + 	commandname = savecmdname;
   1.956 ++//	exsig = 0;
   1.957 + 	exception_handler = savehandler;
   1.958 + 
   1.959 + 	return i;
   1.960 +@@ -9271,7 +9208,7 @@
   1.961 + 	int n = argv[1] ? number(argv[1]) : 1;
   1.962 + 
   1.963 + 	if (n <= 0)
   1.964 +-		ash_msg_and_raise_error(msg_illnum, argv[1]);
   1.965 ++		ash_msg_and_raise_error(illnum, argv[1]);
   1.966 + 	if (n > loopnest)
   1.967 + 		n = loopnest;
   1.968 + 	if (n > 0) {
   1.969 +@@ -10079,7 +10016,7 @@
   1.970 + 		vrandom.flags &= ~VNOFUNC;
   1.971 + 	} else {
   1.972 + 		/* set/reset */
   1.973 +-		random_galois_LFSR = random_LCG = strtoul(value, NULL, 10);
   1.974 ++		random_galois_LFSR = random_LCG = strtoul(value, (char **)NULL, 10);
   1.975 + 	}
   1.976 + }
   1.977 + #endif
   1.978 +@@ -10463,7 +10400,7 @@
   1.979 + 		TRACE(("Here document %d\n", n->type));
   1.980 + 		if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
   1.981 + 			raise_error_syntax("illegal eof marker for << redirection");
   1.982 +-		rmescapes(wordtext, 0);
   1.983 ++		rmescapes(wordtext);
   1.984 + 		here->eofmark = wordtext;
   1.985 + 		here->next = NULL;
   1.986 + 		if (heredoclist == NULL)
   1.987 +@@ -12259,30 +12196,14 @@
   1.988 + 	ap = argptr;
   1.989 + 	if (!*ap) {
   1.990 + 		for (signo = 0; signo < NSIG; signo++) {
   1.991 +-			char *tr = trap_ptr[signo];
   1.992 +-			if (tr) {
   1.993 +-				/* note: bash adds "SIG", but only if invoked
   1.994 +-				 * as "bash". If called as "sh", or if set -o posix,
   1.995 +-				 * then it prints short signal names.
   1.996 +-				 * We are printing short names: */
   1.997 ++			if (trap[signo] != NULL) {
   1.998 + 				out1fmt("trap -- %s %s\n",
   1.999 +-						single_quote(tr),
  1.1000 ++						single_quote(trap[signo]),
  1.1001 + 						get_signame(signo));
  1.1002 +-		/* trap_ptr != trap only if we are in special-cased `trap` code.
  1.1003 +-		 * In this case, we will exit very soon, no need to free(). */
  1.1004 +-				/* if (trap_ptr != trap && tp[0]) */
  1.1005 +-				/*	free(tr); */
  1.1006 + 			}
  1.1007 + 		}
  1.1008 +-		/*
  1.1009 +-		if (trap_ptr != trap) {
  1.1010 +-			free(trap_ptr);
  1.1011 +-			trap_ptr = trap;
  1.1012 +-		}
  1.1013 +-		*/
  1.1014 + 		return 0;
  1.1015 + 	}
  1.1016 +-
  1.1017 + 	action = NULL;
  1.1018 + 	if (ap[1])
  1.1019 + 		action = *ap++;
  1.1020 +@@ -12778,7 +12699,7 @@
  1.1021 + 			mask = 0;
  1.1022 + 			do {
  1.1023 + 				if (*ap >= '8' || *ap < '0')
  1.1024 +-					ash_msg_and_raise_error(msg_illnum, argv[1]);
  1.1025 ++					ash_msg_and_raise_error(illnum, argv[1]);
  1.1026 + 				mask = (mask << 3) + (*ap - '0');
  1.1027 + 			} while (*++ap != '\0');
  1.1028 + 			umask(mask);
  1.1029 +@@ -13039,7 +12960,6 @@
  1.1030 + 	if (p) {
  1.1031 + 		trap[0] = NULL;
  1.1032 + 		evalstring(p, 0);
  1.1033 +-		free(p);
  1.1034 + 	}
  1.1035 + 	flush_stdout_stderr();
  1.1036 +  out:
  1.1037 +@@ -13060,7 +12980,7 @@
  1.1038 + 	/* from var.c: */
  1.1039 + 	{
  1.1040 + 		char **envp;
  1.1041 +-		char ppid[sizeof(int)*3 + 2];
  1.1042 ++		char ppid[sizeof(int)*3 + 1];
  1.1043 + 		const char *p;
  1.1044 + 		struct stat st1, st2;
  1.1045 + 
  1.1046 +@@ -13071,7 +12991,7 @@
  1.1047 + 			}
  1.1048 + 		}
  1.1049 + 
  1.1050 +-		sprintf(ppid, "%u", (unsigned) getppid());
  1.1051 ++		snprintf(ppid, sizeof(ppid), "%u", (unsigned) getppid());
  1.1052 + 		setvar("PPID", ppid, 0);
  1.1053 + 
  1.1054 + 		p = lookupvar("PWD");
  1.1055 +@@ -13311,7 +13231,7 @@
  1.1056 + 	}
  1.1057 + 
  1.1058 + 	if (sflag || minusc == NULL) {
  1.1059 +-#if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
  1.1060 ++#if ENABLE_FEATURE_EDITING_SAVEHISTORY
  1.1061 + 		if (iflag) {
  1.1062 + 			const char *hp = lookupvar("HISTFILE");
  1.1063 + 			if (hp)