xref: /titanic_41/usr/src/lib/libshell/misc/ERRATA.txt (revision b02e9a2d4d2071d770e5aa9ae8f83f2bbe1f2ced)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
22# Use is subject to license terms.
23#
24# ident	"%Z%%M%	%I%	%E% SMI"
25#
26
27#
28# ERRATA.txt
29#
30# Errata/problems/notes about problems in the current sources
31#
32
33######## Errata #001: ########
34Some constants which are larger than 2^32 seem to
35require either "LL" or "ULL" as suffix to get the build compiling - at least in
36OS/Net with it's very strict build flags the problem is that worse that I had
37to use "-Wno-error" in usr/src/lib/libast/Makefile.com for the gcc build to get
38it compiling:
39-- snip --
40pics/$(MACH)/src/lib/libast/conftab.o   := CERRWARN +=
41-erroff=E_C99_INTEGER_PROMOTION
42pics/$(MACH)/src/lib/libast/conftab.o \
43pics/$(MACH64)/src/lib/libast/conftab.o := CERRWARN +=
44-erroff=E_INTEGRAL_CONSTANT_TOO_LARGE
45pics/$(MACH)/src/lib/libast/conftab.o \
46pics/$(MACH64)/src/lib/libast/conftab.o := CERRWARN +=
47-erroff=E_INTEGER_OVERFLOW_DETECTED
48pics/$(MACH)/src/lib/libast/conftab.o \
49pics/$(MACH64)/src/lib/libast/conftab.o := CERRWARN += -_gcc=-Wno-error
50pics/common/hash/
51-- snip --
52
53The following diff has been used to (temporarily work around the problem:
54-- snip --
55Index: src/lib/libast/sparcv9/src/lib/libast/conftab.c
56===================================================================
57--- src/lib/libast/sparcv9/src/lib/libast/conftab.c	(revision 664)
58+++ src/lib/libast/sparcv9/src/lib/libast/conftab.c	(working copy)
59@@ -220,8 +220,8 @@
60 { "LFS_LINTFLAGS", { 0, 0 }, { 0, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_STRING, CONF_POSIX, 1, CONF_confstr, _CS_LFS_LINTFLAGS },
61 { "LINE_MAX", { 0, 0 }, { _POSIX2_LINE_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_NOSECTION|CONF_MINMAX_DEF, CONF_POSIX, 2, CONF_sysconf, _SC_LINE_MAX },
62 { "LINK_MAX", { 0, 0 }, { _POSIX_LINK_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_pathconf, _PC_LINK_MAX },
63-{ "LLONG_MAX", { 9223372036854775807, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
64-{ "LLONG_MIN", { -9223372036854775808, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
65+{ "LLONG_MAX", { 9223372036854775807LL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
66+{ "LLONG_MIN", { (-9223372036854775807LL-1LL), 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
67 { "LOCALEDEF", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_LOCALEDEF },
68 { "LOGIN_NAME_MAX", { 0, 0 }, { _POSIX_LOGIN_NAME_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_sysconf, _SC_LOGIN_NAME_MAX },
69 { "LOGNAME_MAX", { 0, 0 }, { 8, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, _SC_LOGNAME_MAX },
70@@ -407,7 +407,7 @@
71 { "UID_MAX", { 0, 0 }, { 60002, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, -1 },
72 { "UINT_MAX", { 0, 0 }, { 0, 0 }, CONF_LIMIT, CONF_C, 1, CONF_nop, -1 },
73 { "UIO_MAXIOV", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE, CONF_POSIX, 1, CONF_nop, -1 },
74-{ "ULLONG_MAX", { 18446744073709551615, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
75+{ "ULLONG_MAX", { 18446744073709551615ULL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
76 { "ULONG_MAX", { 4294967295, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
77 { "UNIX", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_STANDARD|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_XOPEN, 1, CONF_sysconf, _SC_XOPEN_UNIX },
78 { "UPE", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_UPE },
79Index: src/lib/libast/sparc/src/lib/libast/conftab.c
80===================================================================
81--- src/lib/libast/sparc/src/lib/libast/conftab.c	(revision 664)
82+++ src/lib/libast/sparc/src/lib/libast/conftab.c	(working copy)
83@@ -220,8 +220,8 @@
84 { "LFS_LINTFLAGS", { 0, 0 }, { 0, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_STRING, CONF_POSIX, 1, CONF_confstr, _CS_LFS_LINTFLAGS },
85 { "LINE_MAX", { 0, 0 }, { _POSIX2_LINE_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_NOSECTION|CONF_MINMAX_DEF, CONF_POSIX, 2, CONF_sysconf, _SC_LINE_MAX },
86 { "LINK_MAX", { 0, 0 }, { _POSIX_LINK_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_pathconf, _PC_LINK_MAX },
87-{ "LLONG_MAX", { 9223372036854775807, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
88-{ "LLONG_MIN", { -9223372036854775808, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
89+{ "LLONG_MAX", { 9223372036854775807LL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
90+{ "LLONG_MIN", { (-9223372036854775807LL-1LL), 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
91 { "LOCALEDEF", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_LOCALEDEF },
92 { "LOGIN_NAME_MAX", { 0, 0 }, { _POSIX_LOGIN_NAME_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_sysconf, _SC_LOGIN_NAME_MAX },
93 { "LOGNAME_MAX", { 0, 0 }, { 8, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, _SC_LOGNAME_MAX },
94@@ -407,7 +407,7 @@
95 { "UID_MAX", { 0, 0 }, { 60002, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, -1 },
96 { "UINT_MAX", { 0, 0 }, { 0, 0 }, CONF_LIMIT, CONF_C, 1, CONF_nop, -1 },
97 { "UIO_MAXIOV", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE, CONF_POSIX, 1, CONF_nop, -1 },
98-{ "ULLONG_MAX", { 18446744073709551615, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
99+{ "ULLONG_MAX", { 18446744073709551615ULL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
100 { "ULONG_MAX", { 4294967295, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
101 { "UNIX", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_STANDARD|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_XOPEN, 1, CONF_sysconf, _SC_XOPEN_UNIX },
102 { "UPE", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_UPE },
103Index: src/lib/libast/i386/src/lib/libast/conftab.c
104===================================================================
105--- src/lib/libast/i386/src/lib/libast/conftab.c	(revision 664)
106+++ src/lib/libast/i386/src/lib/libast/conftab.c	(working copy)
107@@ -220,8 +220,8 @@
108 { "LFS_LINTFLAGS", { 0, 0 }, { 0, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_STRING, CONF_POSIX, 1, CONF_confstr, _CS_LFS_LINTFLAGS },
109 { "LINE_MAX", { 0, 0 }, { _POSIX2_LINE_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_NOSECTION|CONF_MINMAX_DEF, CONF_POSIX, 2, CONF_sysconf, _SC_LINE_MAX },
110 { "LINK_MAX", { 0, 0 }, { _POSIX_LINK_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_pathconf, _PC_LINK_MAX },
111-{ "LLONG_MAX", { 9223372036854775807, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
112-{ "LLONG_MIN", { -9223372036854775808, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
113+{ "LLONG_MAX", { 9223372036854775807LL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
114+{ "LLONG_MIN", { (-9223372036854775807LL-1LL), 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
115 { "LOCALEDEF", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_LOCALEDEF },
116 { "LOGIN_NAME_MAX", { 0, 0 }, { _POSIX_LOGIN_NAME_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_sysconf, _SC_LOGIN_NAME_MAX },
117 { "LOGNAME_MAX", { 0, 0 }, { 8, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, _SC_LOGNAME_MAX },
118@@ -407,7 +407,7 @@
119 { "UID_MAX", { 0, 0 }, { 60002, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, -1 },
120 { "UINT_MAX", { 0, 0 }, { 0, 0 }, CONF_LIMIT, CONF_C, 1, CONF_nop, -1 },
121 { "UIO_MAXIOV", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE, CONF_POSIX, 1, CONF_nop, -1 },
122-{ "ULLONG_MAX", { 18446744073709551615, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
123+{ "ULLONG_MAX", { 18446744073709551615ULL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
124 { "ULONG_MAX", { 4294967295, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
125 { "UNIX", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_STANDARD|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_XOPEN, 1, CONF_sysconf, _SC_XOPEN_UNIX },
126 { "UPE", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_UPE },
127Index: src/lib/libast/Makefile.com
128===================================================================
129--- src/lib/libast/Makefile.com	(revision 664)
130+++ src/lib/libast/Makefile.com	(working copy)
131@@ -706,11 +706,7 @@
132 CERRWARN += -erroff=E_UNRECOGNIZED_PRAGMA_IGNORED
133 pics/$(MACH)/src/lib/libast/conftab.o	:= CERRWARN += -erroff=E_C99_INTEGER_PROMOTION
134 pics/$(MACH)/src/lib/libast/conftab.o \
135-pics/$(MACH64)/src/lib/libast/conftab.o	:= CERRWARN += -erroff=E_INTEGRAL_CONSTANT_TOO_LARGE
136-pics/$(MACH)/src/lib/libast/conftab.o \
137-pics/$(MACH64)/src/lib/libast/conftab.o	:= CERRWARN += -erroff=E_INTEGER_OVERFLOW_DETECTED
138-pics/$(MACH)/src/lib/libast/conftab.o \
139-pics/$(MACH64)/src/lib/libast/conftab.o	:= CERRWARN += -_gcc=-Wno-error
140+pics/$(MACH64)/src/lib/libast/conftab.o	:= CERRWARN += -erroff=E_INIT_DOES_NOT_FIT
141 pics/common/hash/hashlook.o		:= CERRWARN += -erroff=E_CONST_PROMOTED_UNSIGNED_LONG
142 pics/common/hash/memhash.o		:= CERRWARN += -erroff=E_CONST_PROMOTED_UNSIGNED_LONG
143 pics/common/hash/memsum.o		:= CERRWARN += -erroff=E_CONST_PROMOTED_UNSIGNED_LONG
144Index: src/lib/libast/amd64/src/lib/libast/conftab.c
145===================================================================
146--- src/lib/libast/amd64/src/lib/libast/conftab.c	(revision 664)
147+++ src/lib/libast/amd64/src/lib/libast/conftab.c	(working copy)
148@@ -220,8 +220,8 @@
149 { "LFS_LINTFLAGS", { 0, 0 }, { 0, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_STRING, CONF_POSIX, 1, CONF_confstr, _CS_LFS_LINTFLAGS },
150 { "LINE_MAX", { 0, 0 }, { _POSIX2_LINE_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_NOSECTION|CONF_MINMAX_DEF, CONF_POSIX, 2, CONF_sysconf, _SC_LINE_MAX },
151 { "LINK_MAX", { 0, 0 }, { _POSIX_LINK_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_pathconf, _PC_LINK_MAX },
152-{ "LLONG_MAX", { 9223372036854775807, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
153-{ "LLONG_MIN", { -9223372036854775808, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
154+{ "LLONG_MAX", { 9223372036854775807LL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
155+{ "LLONG_MIN", { (-9223372036854775807LL-1LL), 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
156 { "LOCALEDEF", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_LOCALEDEF },
157 { "LOGIN_NAME_MAX", { 0, 0 }, { _POSIX_LOGIN_NAME_MAX, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_POSIX, 1, CONF_sysconf, _SC_LOGIN_NAME_MAX },
158 { "LOGNAME_MAX", { 0, 0 }, { 8, 0 }, CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, _SC_LOGNAME_MAX },
159@@ -407,7 +407,7 @@
160 { "UID_MAX", { 0, 0 }, { 60002, 0 }, CONF_LIMIT|CONF_MINMAX|CONF_UNDERSCORE|CONF_MINMAX_DEF, CONF_SVID, 1, CONF_sysconf, -1 },
161 { "UINT_MAX", { 0, 0 }, { 0, 0 }, CONF_LIMIT, CONF_C, 1, CONF_nop, -1 },
162 { "UIO_MAXIOV", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE, CONF_POSIX, 1, CONF_nop, -1 },
163-{ "ULLONG_MAX", { 18446744073709551615, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
164+{ "ULLONG_MAX", { 18446744073709551615ULL, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
165 { "ULONG_MAX", { 4294967295, 0 }, { 0, 0 }, CONF_LIMIT|CONF_LIMIT_DEF, CONF_C, 1, CONF_nop, -1 },
166 { "UNIX", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_STANDARD|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_XOPEN, 1, CONF_sysconf, _SC_XOPEN_UNIX },
167 { "UPE", { 0, 0 }, { 0, 0 }, CONF_FEATURE|CONF_UNDERSCORE|CONF_PREFIX_ONLY, CONF_POSIX, 2, CONF_sysconf, _SC_2_UPE },
168-- snip --
169
170This change works around the problems in the generated "conftab.c" ; I'll file a patch against
171"libast/common/comp/conf.sh" later to fix the problem in the upstream sources...
172
173######## Errata #002: ########
174A change to usr/src/lib/libcmd/common/date.c has been applied to prevent
175the string literals (backslashes added to prevent expansion) "%M\%" and "%Y\%"
176from being expanded by the SCCS version control software:
177
178-- snip --
179Index: src/lib/libcmd/common/date.c
180===================================================================
181--- src/lib/libcmd/common/date.c	(revision 694)
182+++ src/lib/libcmd/common/date.c	(working copy)
183@@ -222,13 +222,13 @@
184                *argv++ = s;
185                if (streq(astconf("UNIVERSE", NiL, NiL), "att"))
186                {
187-                       tmxfmt(buf, sizeof(buf), "%m%d%H" "%M%Y.%S", now);
188+                       tmxfmt(buf, sizeof(buf), "%m%d%H" "%M" "%Y.%S", now);
189                        if (adjust)
190                                *argv++ = "-a";
191                }
192                else
193                {
194-                       tmxfmt(buf, sizeof(buf), "%Y%m%d%H" "%M.%S", now);
195+                       tmxfmt(buf, sizeof(buf), "%Y" "%m%d%H" "%M.%S", now);
196                        if (network)
197                                *argv++ = "-n";
198                        if (tm_info.flags & TM_UTC)
199-- snip --
200
201
202######## Errata #003: ########
203A change to usr/src/lib/libshell/common/sh/jobs.c has been applied to handle
204a memory corruption condition caused by a call to |_ast_malloc()| from within
205a signal handler.
206-- snip --
207Index: src/lib/libshell/common/sh/jobs.c
208===================================================================
209--- src/lib/libshell/common/sh/jobs.c	(revision 743)
210+++ src/lib/libshell/common/sh/jobs.c	(working copy)
211@@ -43,6 +24,8 @@
212 #   define WIFCONTINUED(wstat)	(0)
213 #endif
214
215+#define	NJOB_SAVELIST	4
216+
217 /*
218  * temporary hack to get W* macros to work
219  */
220@@ -59,13 +42,35 @@
221 	unsigned short	exitval;
222 };
223
224+static struct jobsave *job_savelist;
225+static int njob_savelist;
226+
227+static void init_savelist(void)
228+{
229+	register struct jobsave *jp;
230+	while(njob_savelist < NJOB_SAVELIST)
231+	{
232+		jp = newof(0,struct jobsave,1,0);
233+		jp->next = job_savelist;
234+		job_savelist = jp;
235+		njob_savelist++;
236+	}
237+}
238+
239 /*
240  * return next on link list of jobsave free list
241  */
242 static struct jobsave *jobsave_create(pid_t pid)
243 {
244-	struct jobsave *jp;
245-	if(jp = newof(0,struct jobsave,1,0))
246+	register struct jobsave *jp = job_savelist;
247+	if(jp)
248+	{
249+		njob_savelist--;
250+		job_savelist = jp->next;
251+	}
252+	else
253+		jp = newof(0,struct jobsave,1,0);
254+	if(jp)
255 		jp->pid = pid;
256 	return(jp);
257 }
258@@ -372,6 +377,8 @@
259 #   if defined(SIGCLD) && (SIGCLD!=SIGCHLD)
260 	signal(SIGCLD,job_waitsafe);
261 #   endif
262+	if(njob_savelist < NJOB_SAVELIST)
263+		init_savelist();
264 	if(!sh_isoption(SH_INTERACTIVE))
265 		return;
266 	/* use new line discipline when available */
267@@ -994,6 +1001,8 @@
268 		free((void*)jp);
269 	}
270 	bck.list = 0;
271+	if(njob_savelist < NJOB_SAVELIST)
272+		init_savelist();
273 	job.pwlist = NIL(struct process*);
274 	job.numpost=0;
275 	job.waitall = 0;
276@@ -1016,6 +1025,8 @@
277 	register struct process *pw;
278 	register History_t *hp = sh.hist_ptr;
279 	sh.jobenv = sh.curenv;
280+	if(njob_savelist < NJOB_SAVELIST)
281+		init_savelist();
282 	if(job.toclear)
283 	{
284 		job_clear();
285@@ -1274,8 +1285,14 @@
286 							px->p_flag &= ~P_EXITSAVE;
287 					}
288 				}
289-				if(!(px=job_unpost(pw,1)) || !job.waitall)
290+				if(!job.waitall)
291+				{
292+					if(!sh_isoption(SH_PIPEFAIL))
293+						job_unpost(pw,1);
294 					break;
295+				}
296+				else if(!(px=job_unpost(pw,1)))
297+					break;
298 				pw = px;
299 				continue;
300 			}
301@@ -1313,6 +1330,8 @@
302 	else
303 		tty_set(-1, 0, NIL(struct termios*));
304 done:
305+	if(!job.waitall && sh_isoption(SH_PIPEFAIL))
306+		return;
307 	if(!sh.intrap)
308 	{
309 		job_lock();
310@@ -1594,7 +1613,14 @@
311 		else
312 			bck.list = jp->next;
313 		bck.count--;
314-		free((void*)jp);
315+		if(njob_savelist < NJOB_SAVELIST)
316+		{
317+			njob_savelist++;
318+			jp->next = job_savelist;
319+			job_savelist = jp;
320+		}
321+		else
322+			free((void*)jp);
323 	}
324 	return(r);
325 }
326-- snip --
327# EOF.
328