xref: /titanic_41/usr/src/lib/libshell/misc/ERRATA.txt (revision 5203bc321053fb87d7073c7640548fab73634793)
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
22#
23# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24#
25
26#
27# ERRATA.txt
28#
29# Errata/problems/notes about problems in the current sources
30#
31
32######## Errata #001: ########
33The usage of |posix_spawn()| has been manually disabled because there seems to be a
34race condition which cases sporadic failures like this:
35-- snip --
36$ builtin | fgrep sum | fgrep sum
37/usr/ast/bin/sum
38/usr/bin/sum
39$ builtin | fgrep sum | fgrep sum
40fgrep: fgrep: cannot execute [Exec format error]
41-- snip --.
42The following files have been changed:
43-- snip --
44Index: src/lib/libast/sparcv9/include/ast/ast_lib.h
45===================================================================
46--- usr/src/lib/libast/sparcv9/include/ast/ast_lib.h	(revision 888)
47+++ usr/src/lib/libast/sparcv9/include/ast/ast_lib.h	(working copy)
48@@ -160,7 +160,7 @@
49 #define _hdr_unistd	1	/* #include <unistd.h> ok */
50 #define _lib_vfork	1	/* vfork exists and it works */
51 #define _real_vfork	1	/* vfork child shares data with parent */
52-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
53+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
54 #define _stream_peek	1	/* ioctl(I_PEEK) works */
55 #define _socket_peek	1	/* recv(MSG_PEEK) works */
56 #define _hdr_string	1	/* #include <string.h> ok */
57Index: src/lib/libast/sparcv9/src/lib/libast/ast_lib.h
58===================================================================
59--- usr/src/lib/libast/sparcv9/src/lib/libast/ast_lib.h	(revision 888)
60+++ usr/src/lib/libast/sparcv9/src/lib/libast/ast_lib.h	(working copy)
61@@ -139,7 +139,7 @@
62 #define _hdr_unistd	1	/* #include <unistd.h> ok */
63 #define _lib_vfork	1	/* vfork exists and it works */
64 #define _real_vfork	1	/* vfork child shares data with parent */
65-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
66+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
67 #define _stream_peek	1	/* ioctl(I_PEEK) works */
68 #define _socket_peek	1	/* recv(MSG_PEEK) works */
69 #define _hdr_string	1	/* #include <string.h> ok */
70Index: src/lib/libast/sparcv9/src/lib/libast/FEATURE/lib
71===================================================================
72--- usr/src/lib/libast/sparcv9/src/lib/libast/FEATURE/lib	(revision 888)
73+++ usr/src/lib/libast/sparcv9/src/lib/libast/FEATURE/lib	(working copy)
74@@ -139,7 +139,7 @@
75 #define _hdr_unistd	1	/* #include <unistd.h> ok */
76 #define _lib_vfork	1	/* vfork exists and it works */
77 #define _real_vfork	1	/* vfork child shares data with parent */
78-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
79+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
80 #define _stream_peek	1	/* ioctl(I_PEEK) works */
81 #define _socket_peek	1	/* recv(MSG_PEEK) works */
82 #define _hdr_string	1	/* #include <string.h> ok */
83Index: src/lib/libast/sparc/include/ast/ast_lib.h
84===================================================================
85--- usr/src/lib/libast/sparc/include/ast/ast_lib.h	(revision 888)
86+++ usr/src/lib/libast/sparc/include/ast/ast_lib.h	(working copy)
87@@ -171,7 +171,7 @@
88 #define _hdr_unistd	1	/* #include <unistd.h> ok */
89 #define _lib_vfork	1	/* vfork exists and it works */
90 #define _real_vfork	1	/* vfork child shares data with parent */
91-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
92+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
93 #define _stream_peek	1	/* ioctl(I_PEEK) works */
94 #define _socket_peek	1	/* recv(MSG_PEEK) works */
95 #define _hdr_string	1	/* #include <string.h> ok */
96Index: src/lib/libast/sparc/src/lib/libast/ast_lib.h
97===================================================================
98--- usr/src/lib/libast/sparc/src/lib/libast/ast_lib.h	(revision 888)
99+++ usr/src/lib/libast/sparc/src/lib/libast/ast_lib.h	(working copy)
100@@ -150,7 +150,7 @@
101 #define _hdr_unistd	1	/* #include <unistd.h> ok */
102 #define _lib_vfork	1	/* vfork exists and it works */
103 #define _real_vfork	1	/* vfork child shares data with parent */
104-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
105+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
106 #define _stream_peek	1	/* ioctl(I_PEEK) works */
107 #define _socket_peek	1	/* recv(MSG_PEEK) works */
108 #define _hdr_string	1	/* #include <string.h> ok */
109Index: src/lib/libast/sparc/src/lib/libast/FEATURE/lib
110===================================================================
111--- usr/src/lib/libast/sparc/src/lib/libast/FEATURE/lib	(revision 888)
112+++ usr/src/lib/libast/sparc/src/lib/libast/FEATURE/lib	(working copy)
113@@ -150,7 +150,7 @@
114 #define _hdr_unistd	1	/* #include <unistd.h> ok */
115 #define _lib_vfork	1	/* vfork exists and it works */
116 #define _real_vfork	1	/* vfork child shares data with parent */
117-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
118+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
119 #define _stream_peek	1	/* ioctl(I_PEEK) works */
120 #define _socket_peek	1	/* recv(MSG_PEEK) works */
121 #define _hdr_string	1	/* #include <string.h> ok */
122Index: src/lib/libast/i386/include/ast/ast_lib.h
123===================================================================
124--- usr/src/lib/libast/i386/include/ast/ast_lib.h	(revision 888)
125+++ usr/src/lib/libast/i386/include/ast/ast_lib.h	(working copy)
126@@ -171,7 +171,7 @@
127 #define _hdr_unistd	1	/* #include <unistd.h> ok */
128 #define _lib_vfork	1	/* vfork exists and it works */
129 #define _real_vfork	1	/* vfork child shares data with parent */
130-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
131+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
132 #define _stream_peek	1	/* ioctl(I_PEEK) works */
133 #define _socket_peek	1	/* recv(MSG_PEEK) works */
134 #define _hdr_string	1	/* #include <string.h> ok */
135Index: src/lib/libast/i386/src/lib/libast/ast_lib.h
136===================================================================
137--- usr/src/lib/libast/i386/src/lib/libast/ast_lib.h	(revision 888)
138+++ usr/src/lib/libast/i386/src/lib/libast/ast_lib.h	(working copy)
139@@ -150,7 +150,7 @@
140 #define _hdr_unistd	1	/* #include <unistd.h> ok */
141 #define _lib_vfork	1	/* vfork exists and it works */
142 #define _real_vfork	1	/* vfork child shares data with parent */
143-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
144+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
145 #define _stream_peek	1	/* ioctl(I_PEEK) works */
146 #define _socket_peek	1	/* recv(MSG_PEEK) works */
147 #define _hdr_string	1	/* #include <string.h> ok */
148Index: src/lib/libast/i386/src/lib/libast/FEATURE/lib
149===================================================================
150--- usr/src/lib/libast/i386/src/lib/libast/FEATURE/lib	(revision 888)
151+++ usr/src/lib/libast/i386/src/lib/libast/FEATURE/lib	(working copy)
152@@ -150,7 +150,7 @@
153 #define _hdr_unistd	1	/* #include <unistd.h> ok */
154 #define _lib_vfork	1	/* vfork exists and it works */
155 #define _real_vfork	1	/* vfork child shares data with parent */
156-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
157+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
158 #define _stream_peek	1	/* ioctl(I_PEEK) works */
159 #define _socket_peek	1	/* recv(MSG_PEEK) works */
160 #define _hdr_string	1	/* #include <string.h> ok */
161Index: src/lib/libast/amd64/include/ast/ast_lib.h
162===================================================================
163--- usr/src/lib/libast/amd64/include/ast/ast_lib.h	(revision 888)
164+++ usr/src/lib/libast/amd64/include/ast/ast_lib.h	(working copy)
165@@ -160,7 +160,7 @@
166 #define _hdr_unistd	1	/* #include <unistd.h> ok */
167 #define _lib_vfork	1	/* vfork exists and it works */
168 #define _real_vfork	1	/* vfork child shares data with parent */
169-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
170+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
171 #define _stream_peek	1	/* ioctl(I_PEEK) works */
172 #define _socket_peek	1	/* recv(MSG_PEEK) works */
173 #define _hdr_string	1	/* #include <string.h> ok */
174Index: src/lib/libast/amd64/src/lib/libast/ast_lib.h
175===================================================================
176--- usr/src/lib/libast/amd64/src/lib/libast/ast_lib.h	(revision 888)
177+++ usr/src/lib/libast/amd64/src/lib/libast/ast_lib.h	(working copy)
178@@ -139,7 +139,7 @@
179 #define _hdr_unistd	1	/* #include <unistd.h> ok */
180 #define _lib_vfork	1	/* vfork exists and it works */
181 #define _real_vfork	1	/* vfork child shares data with parent */
182-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
183+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
184 #define _stream_peek	1	/* ioctl(I_PEEK) works */
185 #define _socket_peek	1	/* recv(MSG_PEEK) works */
186 #define _hdr_string	1	/* #include <string.h> ok */
187Index: src/lib/libast/amd64/src/lib/libast/FEATURE/lib
188===================================================================
189--- usr/src/lib/libast/amd64/src/lib/libast/FEATURE/lib	(revision 888)
190+++ usr/src/lib/libast/amd64/src/lib/libast/FEATURE/lib	(working copy)
191@@ -139,7 +139,7 @@
192 #define _hdr_unistd	1	/* #include <unistd.h> ok */
193 #define _lib_vfork	1	/* vfork exists and it works */
194 #define _real_vfork	1	/* vfork child shares data with parent */
195-#define _lib_posix_spawn	2	/* posix_spawn exists and it works and its worth using */
196+#define _lib_posix_spawn	1	/* posix_spawn exists and it works and its worth using */
197 #define _stream_peek	1	/* ioctl(I_PEEK) works */
198 #define _socket_peek	1	/* recv(MSG_PEEK) works */
199 #define _hdr_string	1	/* #include <string.h> ok */
200-- snip --
201
202
203######## Errata #002: ########
204The usage of |mmap()| has been manually enabled to improve I/O performance.
205The following files have been changed:
206-- snip --
207Index: usr/src/lib/libast/sparcv9/include/ast/ast_mmap.h
208===================================================================
209--- usr/src/lib/libast/sparcv9/include/ast/ast_mmap.h	(revision 1701)
210+++ usr/src/lib/libast/sparcv9/include/ast/ast_mmap.h	(working copy)
211@@ -28,6 +28,7 @@
212 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
213 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
214 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
215+#define _mmap_worthy	2	/* mmap is good */
216
217 /* some systems get it wrong but escape concise detection */
218 #ifndef _NO_MMAP
219Index: usr/src/lib/libast/sparcv9/src/lib/libast/ast_mmap.h
220===================================================================
221--- usr/src/lib/libast/sparcv9/src/lib/libast/ast_mmap.h	(revision 1701)
222+++ usr/src/lib/libast/sparcv9/src/lib/libast/ast_mmap.h	(working copy)
223@@ -7,6 +7,7 @@
224 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
225 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
226 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
227+#define _mmap_worthy	2	/* mmap is good */
228
229 /* some systems get it wrong but escape concise detection */
230 #ifndef _NO_MMAP
231Index: usr/src/lib/libast/sparcv9/src/lib/libast/FEATURE/mmap
232===================================================================
233--- usr/src/lib/libast/sparcv9/src/lib/libast/FEATURE/mmap	(revision 1701)
234+++ usr/src/lib/libast/sparcv9/src/lib/libast/FEATURE/mmap	(working copy)
235@@ -7,6 +7,7 @@
236 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
237 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
238 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
239+#define _mmap_worthy	2	/* mmap is good */
240
241 /* some systems get it wrong but escape concise detection */
242 #ifndef _NO_MMAP
243Index: usr/src/lib/libast/sparc/include/ast/ast_mmap.h
244===================================================================
245--- usr/src/lib/libast/sparc/include/ast/ast_mmap.h	(revision 1701)
246+++ usr/src/lib/libast/sparc/include/ast/ast_mmap.h	(working copy)
247@@ -28,7 +28,7 @@
248 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
249 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
250 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
251-#define _mmap_worthy	1	/* mmap is good */
252+#define _mmap_worthy	2	/* mmap is good */
253
254 /* some systems get it wrong but escape concise detection */
255 #ifndef _NO_MMAP
256Index: usr/src/lib/libast/sparc/src/lib/libast/ast_mmap.h
257===================================================================
258--- usr/src/lib/libast/sparc/src/lib/libast/ast_mmap.h	(revision 1701)
259+++ usr/src/lib/libast/sparc/src/lib/libast/ast_mmap.h	(working copy)
260@@ -7,7 +7,7 @@
261 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
262 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
263 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
264-#define _mmap_worthy	1	/* mmap is good */
265+#define _mmap_worthy	2	/* mmap is good */
266
267 /* some systems get it wrong but escape concise detection */
268 #ifndef _NO_MMAP
269Index: usr/src/lib/libast/sparc/src/lib/libast/FEATURE/mmap
270===================================================================
271--- usr/src/lib/libast/sparc/src/lib/libast/FEATURE/mmap	(revision 1701)
272+++ usr/src/lib/libast/sparc/src/lib/libast/FEATURE/mmap	(working copy)
273@@ -7,7 +7,7 @@
274 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
275 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
276 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
277-#define _mmap_worthy	1	/* mmap is good */
278+#define _mmap_worthy	2	/* mmap is good */
279
280 /* some systems get it wrong but escape concise detection */
281 #ifndef _NO_MMAP
282Index: usr/src/lib/libast/i386/include/ast/ast_mmap.h
283===================================================================
284--- usr/src/lib/libast/i386/include/ast/ast_mmap.h	(revision 1701)
285+++ usr/src/lib/libast/i386/include/ast/ast_mmap.h	(working copy)
286@@ -28,6 +28,7 @@
287 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
288 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
289 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
290+#define _mmap_worthy	2	/* mmap is good */
291
292 /* some systems get it wrong but escape concise detection */
293 #ifndef _NO_MMAP
294Index: usr/src/lib/libast/i386/src/lib/libast/ast_mmap.h
295===================================================================
296--- usr/src/lib/libast/i386/src/lib/libast/ast_mmap.h	(revision 1701)
297+++ usr/src/lib/libast/i386/src/lib/libast/ast_mmap.h	(working copy)
298@@ -7,6 +7,7 @@
299 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
300 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
301 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
302+#define _mmap_worthy	2	/* mmap is good */
303
304 /* some systems get it wrong but escape concise detection */
305 #ifndef _NO_MMAP
306Index: usr/src/lib/libast/i386/src/lib/libast/FEATURE/mmap
307===================================================================
308--- usr/src/lib/libast/i386/src/lib/libast/FEATURE/mmap	(revision 1701)
309+++ usr/src/lib/libast/i386/src/lib/libast/FEATURE/mmap	(working copy)
310@@ -7,6 +7,7 @@
311 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
312 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
313 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
314+#define _mmap_worthy	2	/* mmap is good */
315
316 /* some systems get it wrong but escape concise detection */
317 #ifndef _NO_MMAP
318Index: usr/src/lib/libast/amd64/include/ast/ast_mmap.h
319===================================================================
320--- usr/src/lib/libast/amd64/include/ast/ast_mmap.h	(revision 1701)
321+++ usr/src/lib/libast/amd64/include/ast/ast_mmap.h	(working copy)
322@@ -28,6 +28,7 @@
323 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
324 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
325 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
326+#define _mmap_worthy	2	/* mmap is good */
327
328 /* some systems get it wrong but escape concise detection */
329 #ifndef _NO_MMAP
330Index: usr/src/lib/libast/amd64/src/lib/libast/ast_mmap.h
331===================================================================
332--- usr/src/lib/libast/amd64/src/lib/libast/ast_mmap.h	(revision 1701)
333+++ usr/src/lib/libast/amd64/src/lib/libast/ast_mmap.h	(working copy)
334@@ -7,6 +7,7 @@
335 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
336 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
337 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
338+#define _mmap_worthy	2	/* mmap is good */
339
340 /* some systems get it wrong but escape concise detection */
341 #ifndef _NO_MMAP
342Index: usr/src/lib/libast/amd64/src/lib/libast/FEATURE/mmap
343===================================================================
344--- usr/src/lib/libast/amd64/src/lib/libast/FEATURE/mmap	(revision 1701)
345+++ usr/src/lib/libast/amd64/src/lib/libast/FEATURE/mmap	(working copy)
346@@ -7,6 +7,7 @@
347 #define _lib_mmap64	1	/* mmap64 interface and implementation work */
348 #define _mmap_anon	1	/* use mmap MAP_ANON to get raw memory */
349 #define _mmap_devzero	1	/* use mmap on /dev/zero to get raw memory */
350+#define _mmap_worthy	2	/* mmap is good */
351
352 /* some systems get it wrong but escape concise detection */
353 #ifndef _NO_MMAP
354-- snip --
355
356
357######## Errata #003: ########
358A workaround was added for a problem with the "multiline" editor mode which
359occurs when the edit line becomes longer than the terminal's width and the
360terminal cursor is not at position 0 when PS1 is send to the terminal.
361
362For example: The user executes a $ printf "foo"<enter> # the prompt will start
363at position 3 instead of 0. If the user enters a command which is longer than
364the terminal width and then removes enougth characters that the edit line fits
365again into one line the "foo" at the beginning will be overwritten with the
366prompt.
367
368The workaround is to add $(printf "%*s\r%s" COLUMNS "") at the beginning of
369PS1 set by /etc/ksh.kshrc, this causes the shell to move to the beginning
370of the next line if the terminal cursor is not at position 0.
371
372
373######## Errata #004: ########
374The POSIX "cksum"/CRC and AT&T "sum" codepaths in libsum have been reworked
375and then backpoprted to address a performance regression on some
376machine/architecture combinations.
377The following files have been changed:
378-- snip --
379Index: usr/src/lib/libsum/common/sum-crc.c
380===================================================================
381--- usr/src/lib/libsum/common/sum-crc.c	(revision 1724)
382+++ usr/src/lib/libsum/common/sum-crc.c	(working copy)
383@@ -48,7 +48,8 @@
384 	Crcnum_t		init;
385 	Crcnum_t		done;
386 	Crcnum_t		xorsize;
387-	Crcnum_t		tab[256];
388+	const Crcnum_t		*tab; /* use |const| to give the compiler a hint that the data won't change */
389+	Crcnum_t		tabdata[256];
390 	unsigned int		addsize;
391 	unsigned int		rotate;
392 } Crc_t;
393@@ -56,6 +57,62 @@
394 #define CRC(p,s,c)		(s = (s >> 8) ^ (p)->tab[(s ^ (c)) & 0xff])
395 #define CRCROTATE(p,s,c)	(s = (s << 8) ^ (p)->tab[((s >> 24) ^ (c)) & 0xff])
396
397+static const
398+Crcnum_t posix_cksum_tab[256] = {
399+	0x00000000U,
400+	0x04c11db7U, 0x09823b6eU, 0x0d4326d9U, 0x130476dcU, 0x17c56b6bU,
401+	0x1a864db2U, 0x1e475005U, 0x2608edb8U, 0x22c9f00fU, 0x2f8ad6d6U,
402+	0x2b4bcb61U, 0x350c9b64U, 0x31cd86d3U, 0x3c8ea00aU, 0x384fbdbdU,
403+	0x4c11db70U, 0x48d0c6c7U, 0x4593e01eU, 0x4152fda9U, 0x5f15adacU,
404+	0x5bd4b01bU, 0x569796c2U, 0x52568b75U, 0x6a1936c8U, 0x6ed82b7fU,
405+	0x639b0da6U, 0x675a1011U, 0x791d4014U, 0x7ddc5da3U, 0x709f7b7aU,
406+	0x745e66cdU, 0x9823b6e0U, 0x9ce2ab57U, 0x91a18d8eU, 0x95609039U,
407+	0x8b27c03cU, 0x8fe6dd8bU, 0x82a5fb52U, 0x8664e6e5U, 0xbe2b5b58U,
408+	0xbaea46efU, 0xb7a96036U, 0xb3687d81U, 0xad2f2d84U, 0xa9ee3033U,
409+	0xa4ad16eaU, 0xa06c0b5dU, 0xd4326d90U, 0xd0f37027U, 0xddb056feU,
410+	0xd9714b49U, 0xc7361b4cU, 0xc3f706fbU, 0xceb42022U, 0xca753d95U,
411+	0xf23a8028U, 0xf6fb9d9fU, 0xfbb8bb46U, 0xff79a6f1U, 0xe13ef6f4U,
412+	0xe5ffeb43U, 0xe8bccd9aU, 0xec7dd02dU, 0x34867077U, 0x30476dc0U,
413+	0x3d044b19U, 0x39c556aeU, 0x278206abU, 0x23431b1cU, 0x2e003dc5U,
414+	0x2ac12072U, 0x128e9dcfU, 0x164f8078U, 0x1b0ca6a1U, 0x1fcdbb16U,
415+	0x018aeb13U, 0x054bf6a4U, 0x0808d07dU, 0x0cc9cdcaU, 0x7897ab07U,
416+	0x7c56b6b0U, 0x71159069U, 0x75d48ddeU, 0x6b93dddbU, 0x6f52c06cU,
417+	0x6211e6b5U, 0x66d0fb02U, 0x5e9f46bfU, 0x5a5e5b08U, 0x571d7dd1U,
418+	0x53dc6066U, 0x4d9b3063U, 0x495a2dd4U, 0x44190b0dU, 0x40d816baU,
419+	0xaca5c697U, 0xa864db20U, 0xa527fdf9U, 0xa1e6e04eU, 0xbfa1b04bU,
420+	0xbb60adfcU, 0xb6238b25U, 0xb2e29692U, 0x8aad2b2fU, 0x8e6c3698U,
421+	0x832f1041U, 0x87ee0df6U, 0x99a95df3U, 0x9d684044U, 0x902b669dU,
422+	0x94ea7b2aU, 0xe0b41de7U, 0xe4750050U, 0xe9362689U, 0xedf73b3eU,
423+	0xf3b06b3bU, 0xf771768cU, 0xfa325055U, 0xfef34de2U, 0xc6bcf05fU,
424+	0xc27dede8U, 0xcf3ecb31U, 0xcbffd686U, 0xd5b88683U, 0xd1799b34U,
425+	0xdc3abdedU, 0xd8fba05aU, 0x690ce0eeU, 0x6dcdfd59U, 0x608edb80U,
426+	0x644fc637U, 0x7a089632U, 0x7ec98b85U, 0x738aad5cU, 0x774bb0ebU,
427+	0x4f040d56U, 0x4bc510e1U, 0x46863638U, 0x42472b8fU, 0x5c007b8aU,
428+	0x58c1663dU, 0x558240e4U, 0x51435d53U, 0x251d3b9eU, 0x21dc2629U,
429+	0x2c9f00f0U, 0x285e1d47U, 0x36194d42U, 0x32d850f5U, 0x3f9b762cU,
430+	0x3b5a6b9bU, 0x0315d626U, 0x07d4cb91U, 0x0a97ed48U, 0x0e56f0ffU,
431+	0x1011a0faU, 0x14d0bd4dU, 0x19939b94U, 0x1d528623U, 0xf12f560eU,
432+	0xf5ee4bb9U, 0xf8ad6d60U, 0xfc6c70d7U, 0xe22b20d2U, 0xe6ea3d65U,
433+	0xeba91bbcU, 0xef68060bU, 0xd727bbb6U, 0xd3e6a601U, 0xdea580d8U,
434+	0xda649d6fU, 0xc423cd6aU, 0xc0e2d0ddU, 0xcda1f604U, 0xc960ebb3U,
435+	0xbd3e8d7eU, 0xb9ff90c9U, 0xb4bcb610U, 0xb07daba7U, 0xae3afba2U,
436+	0xaafbe615U, 0xa7b8c0ccU, 0xa379dd7bU, 0x9b3660c6U, 0x9ff77d71U,
437+	0x92b45ba8U, 0x9675461fU, 0x8832161aU, 0x8cf30badU, 0x81b02d74U,
438+	0x857130c3U, 0x5d8a9099U, 0x594b8d2eU, 0x5408abf7U, 0x50c9b640U,
439+	0x4e8ee645U, 0x4a4ffbf2U, 0x470cdd2bU, 0x43cdc09cU, 0x7b827d21U,
440+	0x7f436096U, 0x7200464fU, 0x76c15bf8U, 0x68860bfdU, 0x6c47164aU,
441+	0x61043093U, 0x65c52d24U, 0x119b4be9U, 0x155a565eU, 0x18197087U,
442+	0x1cd86d30U, 0x029f3d35U, 0x065e2082U, 0x0b1d065bU, 0x0fdc1becU,
443+	0x3793a651U, 0x3352bbe6U, 0x3e119d3fU, 0x3ad08088U, 0x2497d08dU,
444+	0x2056cd3aU, 0x2d15ebe3U, 0x29d4f654U, 0xc5a92679U, 0xc1683bceU,
445+	0xcc2b1d17U, 0xc8ea00a0U, 0xd6ad50a5U, 0xd26c4d12U, 0xdf2f6bcbU,
446+	0xdbee767cU, 0xe3a1cbc1U, 0xe760d676U, 0xea23f0afU, 0xeee2ed18U,
447+	0xf0a5bd1dU, 0xf464a0aaU, 0xf9278673U, 0xfde69bc4U, 0x89b8fd09U,
448+	0x8d79e0beU, 0x803ac667U, 0x84fbdbd0U, 0x9abc8bd5U, 0x9e7d9662U,
449+	0x933eb0bbU, 0x97ffad0cU, 0xafb010b1U, 0xab710d06U, 0xa6322bdfU,
450+	0xa2f33668U, 0xbcb4666dU, 0xb8757bdaU, 0xb5365d03U, 0xb1f740b4U
451+};
452+
453 static Sum_t*
454 crc_open(const Method_t* method, const char* name)
455 {
456@@ -73,62 +130,80 @@
457 		sum->method = (Method_t*)method;
458 		sum->name = name;
459 	}
460-	polynomial = 0xedb88320;
461-	s = name;
462-	while (*(t = s))
463+
464+	if(!strcmp(name, "crc-0x04c11db7-rotate-done-size"))
465 	{
466-		for (t = s, v = 0; *s && *s != '-'; s++)
467-			if (*s == '=' && !v)
468-				v = s;
469-		i = (v ? v : s) - t;
470-		if (isdigit(*t) || v && i >= 4 && strneq(t, "poly", 4) && (t = v + 1))
471-			polynomial = strtoul(t, NiL, 0);
472-		else if (strneq(t, "done", i))
473-			sum->done = v ? strtoul(v + 1, NiL, 0) : ~sum->done;
474-		else if (strneq(t, "init", i))
475-			sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
476-		else if (strneq(t, "rotate", i))
477-			sum->rotate = 1;
478-		else if (strneq(t, "size", i))
479-		{
480-			sum->addsize = 1;
481-			if (v)
482-				sum->xorsize = strtoul(v + 1, NiL, 0);
483-		}
484-		if (*s == '-')
485-			s++;
486+		sum->init=0;
487+		sum->done=0xffffffff;
488+		sum->xorsize=0x0;
489+		sum->addsize=0x1;
490+		sum->rotate=1;
491+
492+		/* Optimized codepath for POSIX cksum to save startup time */
493+		sum->tab=posix_cksum_tab;
494 	}
495-	if (sum->rotate)
496+	else
497 	{
498-		Crcnum_t	t;
499-		Crcnum_t	p[8];
500-
501-		p[0] = polynomial;
502-		for (i = 1; i < 8; i++)
503-			p[i] = (p[i-1] << 1) ^ ((p[i-1] & 0x80000000) ? polynomial : 0);
504-		for (i = 0; i < elementsof(sum->tab); i++)
505+		polynomial = 0xedb88320;
506+		s = name;
507+		while (*(t = s))
508 		{
509-			t = 0;
510-			x = i;
511-			for (j = 0; j < 8; j++)
512+			for (t = s, v = 0; *s && *s != '-'; s++)
513+				if (*s == '=' && !v)
514+					v = s;
515+			i = (v ? v : s) - t;
516+			if (isdigit(*t) || v && i >= 4 && strneq(t, "poly", 4) && (t = v + 1))
517+				polynomial = strtoul(t, NiL, 0);
518+			else if (strneq(t, "done", i))
519+				sum->done = v ? strtoul(v + 1, NiL, 0) : ~sum->done;
520+			else if (strneq(t, "init", i))
521+				sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
522+			else if (strneq(t, "rotate", i))
523+				sum->rotate = 1;
524+			else if (strneq(t, "size", i))
525 			{
526-				if (x & 1)
527-					t ^= p[j];
528-				x >>= 1;
529+				sum->addsize = 1;
530+				if (v)
531+					sum->xorsize = strtoul(v + 1, NiL, 0);
532 			}
533-			sum->tab[i] = t;
534+			if (*s == '-')
535+				s++;
536 		}
537-	}
538-	else
539-	{
540-		for (i = 0; i < elementsof(sum->tab); i++)
541+		if (sum->rotate)
542 		{
543-			x = i;
544-			for (j = 0; j < 8; j++)
545-				x = (x>>1) ^ ((x & 1) ? polynomial : 0);
546-			sum->tab[i] = x;
547+			Crcnum_t	t;
548+			Crcnum_t	p[8];
549+
550+			p[0] = polynomial;
551+			for (i = 1; i < 8; i++)
552+				p[i] = (p[i-1] << 1) ^ ((p[i-1] & 0x80000000) ? polynomial : 0);
553+			for (i = 0; i < elementsof(sum->tabdata); i++)
554+			{
555+				t = 0;
556+				x = i;
557+				for (j = 0; j < 8; j++)
558+				{
559+					if (x & 1)
560+						t ^= p[j];
561+					x >>= 1;
562+				}
563+				sum->tabdata[i] = t;
564+			}
565 		}
566+		else
567+		{
568+			for (i = 0; i < elementsof(sum->tabdata); i++)
569+			{
570+				x = i;
571+				for (j = 0; j < 8; j++)
572+					x = (x>>1) ^ ((x & 1) ? polynomial : 0);
573+				sum->tabdata[i] = x;
574+			}
575+		}
576+
577+		sum->tab=sum->tabdata;
578 	}
579+
580 	return (Sum_t*)sum;
581 }
582
583@@ -141,11 +216,77 @@
584 	return 0;
585 }
586
587+#if defined(__SUNPRO_C) || defined(__GNUC__)
588+
589+#if defined(__SUNPRO_C)
590+#    include <sun_prefetch.h>
591+#    define sum_prefetch(addr) sun_prefetch_read_many((void *)(addr))
592+#elif defined(__GNUC__)
593+#    define sum_prefetch(addr) __builtin_prefetch((addr), 0, 3)
594+#else
595+#    error Unknown compiler
596+#endif
597+
598+#define CBLOCK_SIZE (64)
599+#pragma unroll(16)
600+
601 static int
602 crc_block(Sum_t* p, const void* s, size_t n)
603 {
604 	Crc_t*			sum = (Crc_t*)p;
605 	register Crcnum_t	c = sum->sum;
606+	register const unsigned char*	b = (const unsigned char*)s;
607+	register const unsigned char*	e = b + n;
608+	unsigned short i;
609+
610+	sum_prefetch(b);
611+
612+	if (sum->rotate)
613+	{
614+		while (n > CBLOCK_SIZE)
615+		{
616+			sum_prefetch(b+CBLOCK_SIZE);
617+			for(i=0 ; i < CBLOCK_SIZE ; i++)
618+			{
619+				CRCROTATE(sum, c, *b++);
620+			}
621+
622+			n-=CBLOCK_SIZE;
623+		}
624+
625+		while (b < e)
626+		{
627+			CRCROTATE(sum, c, *b++);
628+		}
629+	}
630+	else
631+	{
632+		while (n > CBLOCK_SIZE)
633+		{
634+			sum_prefetch(b+CBLOCK_SIZE);
635+			for(i=0 ; i < CBLOCK_SIZE ; i++)
636+			{
637+				CRC(sum, c, *b++);
638+			}
639+
640+			n-=CBLOCK_SIZE;
641+		}
642+
643+		while (b < e)
644+		{
645+			CRC(sum, c, *b++);
646+		}
647+	}
648+
649+	sum->sum = c;
650+	return 0;
651+}
652+#else
653+static int
654+crc_block(Sum_t* p, const void* s, size_t n)
655+{
656+	Crc_t*			sum = (Crc_t*)p;
657+	register Crcnum_t	c = sum->sum;
658 	register unsigned char*	b = (unsigned char*)s;
659 	register unsigned char*	e = b + n;
660
661@@ -158,6 +299,7 @@
662 	sum->sum = c;
663 	return 0;
664 }
665+#endif /* defined(__SUNPRO_C) || defined(__GNUC__) */
666
667 static int
668 crc_done(Sum_t* p)
669Index: usr/src/lib/libsum/common/sum-att.c
670===================================================================
671--- usr/src/lib/libsum/common/sum-att.c	(revision 1724)
672+++ usr/src/lib/libsum/common/sum-att.c	(working copy)
673@@ -35,10 +35,73 @@
674 #define att_data	long_data
675 #define att_scale	512
676
677+#if defined(__SUNPRO_C) || defined(__GNUC__)
678+
679+#if defined(__SUNPRO_C)
680+#    include <sun_prefetch.h>
681+#    define sum_prefetch(addr) sun_prefetch_read_many((void *)(addr))
682+#elif defined(__GNUC__)
683+#    define sum_prefetch(addr) __builtin_prefetch((addr), 0, 3)
684+#else
685+#    error Unknown compiler
686+#endif
687+
688+#define CBLOCK_SIZE (64)
689+#pragma unroll(16)
690+
691+/* Inmos transputer would love this algorithm */
692 static int
693 att_block(register Sum_t* p, const void* s, size_t n)
694 {
695 	register uint32_t	c = ((Integral_t*)p)->sum;
696+	register const unsigned char*	b = (const unsigned char*)s;
697+	register const unsigned char*	e = b + n;
698+	register uint32_t s0, s1, s2, s3, s4, s5, s6, s7;
699+	register unsigned int i;
700+
701+	s0=s1=s2=s3=s4=s5=s6=s7=0U;
702+
703+	sum_prefetch((void *)b);
704+
705+	while (n > CBLOCK_SIZE)
706+	{
707+		sum_prefetch((b+CBLOCK_SIZE));
708+
709+		/* Compiler will unroll for() loops per #pragma unroll */
710+		for (i=0 ; i < (CBLOCK_SIZE/8) ; i++)
711+		{
712+			/*
713+			 * use s0-s7 to decouple calculations (this improves pipelining)
714+			 * because each operation is completely independent from it's
715+			 * siblings
716+			 */
717+			s0+=b[0];
718+			s1+=b[1];
719+			s2+=b[2];
720+			s3+=b[3];
721+			s4+=b[4];
722+			s5+=b[5];
723+			s6+=b[6];
724+			s7+=b[7];
725+
726+			b+=8;
727+			n-=8;
728+		}
729+	}
730+
731+	c+=s0+s1+s2+s3+s4+s5+s6+s7;
732+
733+	while (b < e)
734+		c += *b++;
735+	((Integral_t*)p)->sum = c;
736+	return 0;
737+}
738+
739+#else
740+static int
741+att_block(register Sum_t* p, const void* s, size_t n)
742+{
743+	register uint32_t	c = ((Integral_t*)p)->sum;
744 	register unsigned char*	b = (unsigned char*)s;
745 	register unsigned char*	e = b + n;
746
747@@ -47,6 +110,7 @@
748 	((Integral_t*)p)->sum = c;
749 	return 0;
750 }
751+#endif /* defined(__SUNPRO_C) || defined(__GNUC__) */
752
753 static int
754 att_done(Sum_t* p)
755-- snip --
756
757
758
759######## Errata #005: ########
760A fix for an off-by-one buffer overflow in the regex expression cache
761has been backported.
762The following files have been changed:
763-- snip --
764Index: usr/src/lib/libast/common/regex/regcache.c
765===================================================================
766--- usr/src/lib/libast/common/regex/regcache.c	(revision 1821)
767+++ usr/src/lib/libast/common/regex/regcache.c	(working copy)
768@@ -166,7 +166,7 @@
769 			cp->keep = 0;
770 			regfree(&cp->re);
771 		}
772-		if ((i = strlen(pattern)) >= cp->size)
773+		if ((i = strlen(pattern) + 1) >= cp->size)
774 		{
775 			cp->size = roundof(i, ROUND);
776 			if (!(cp->pattern = newof(cp->pattern, char, cp->size, 0)))
777-- snip --
778
779
780######## Errata #006: ########
781A fix for an issue with tail -f becoming stuck after a few 1000 lines
782has been backported:
783The following files have been changed:
784-- snip --
785Index: usr/src/lib/libcmd/common/tail.c
786===================================================================
787--- usr/src/lib/libcmd/common/tail.c	(revision 1822)
788+++ usr/src/lib/libcmd/common/tail.c	(working copy)
789@@ -28,7 +28,7 @@
790  */
791
792 static const char usage[] =
793-"+[-?\n@(#)$Id: tail (AT&T Research) 2010-03-07 $\n]"
794+"+[-?\n@(#)$Id: tail (AT&T Research) 2010-03-23 $\n]"
795 USAGE_LICENSE
796 "[+NAME?tail - output trailing portion of one or more files ]"
797 "[+DESCRIPTION?\btail\b copies one or more input files to standard output "
798@@ -647,16 +647,14 @@
799 					error(ERROR_system(0), "%s: cannot stat", fp->name);
800 				else if (fp->fifo || fp->end < st.st_size)
801 				{
802-					fp->end = st.st_size;
803 					n = 1;
804 					if (timeout)
805 						fp->expire = NOW + timeout;
806-					z = fp->fifo ? SF_UNBOUND : fp->end - fp->cur;
807+					z = fp->fifo ? SF_UNBOUND : st.st_size - fp->cur;
808 					i = 0;
809 					if ((s = sfreserve(fp->sp, z, SF_LOCKR)) || (z = sfvalue(fp->sp)) && (s = sfreserve(fp->sp, z, SF_LOCKR)) && (i = 1))
810 					{
811-						if (fp->fifo)
812-							z = sfvalue(fp->sp);
813+						z = sfvalue(fp->sp);
814 						for (r = s + z; r > s && *(r - 1) != '\n'; r--);
815 						if ((w = r - s) || i && (w = z))
816 						{
817@@ -672,6 +670,7 @@
818 						else
819 							w = 0;
820 						sfread(fp->sp, s, w);
821+						fp->end += w;
822 					}
823 					goto next;
824 				}
825-- snip --
826
827
828
829
830######## Errata #007: ########
831A warning for shcomp -n has been backported from ksh93 version 'u' to
832handle the possible loss of precision in (( var=$var2 )) vs.
833(( var=var2 )):
834The following files have been changed:
835-- snip --
836Index: usr/src/lib/libshell/common/sh/parse.c
837===================================================================
838--- usr/src/lib/libshell/common/sh/parse.c	(revision 1822)
839+++ usr/src/lib/libshell/common/sh/parse.c	(working copy)
840@@ -247,6 +247,34 @@
841 	return(par);
842 }
843
844+static int paramsub(const char *str)
845+{
846+	register int c,sub=0,lit=0;
847+	while(c= *str++)
848+	{
849+		if(c=='$' && !lit)
850+		{
851+			if(*str=='(')
852+				return(0);
853+			if(sub)
854+				continue;
855+			if(*str=='{')
856+				str++;
857+			if(!isdigit(*str) && strchr("?#@*!$ ",*str)==0)
858+				return(1);
859+		}
860+		else if(c=='`')
861+			return(0);
862+		else if(c=='[' && !lit)
863+			sub++;
864+		else if(c==']' && !lit)
865+			sub--;
866+		else if(c=='\'')
867+			lit = !lit;
868+	}
869+	return(0);
870+}
871+
872 static Shnode_t *getanode(Lex_t *lp, struct argnod *ap)
873 {
874 	register Shnode_t *t = getnode(arithnod);
875@@ -256,7 +284,11 @@
876 	if(ap->argflag&ARG_RAW)
877 		t->ar.arcomp = sh_arithcomp(ap->argval);
878 	else
879+	{
880+		if(sh_isoption(SH_NOEXEC) && (ap->argflag&ARG_MAC) && paramsub(ap->argval))
881+			errormsg(SH_DICT,ERROR_warn(0),"%d: parameter substitution requires unnecessary string to number conversion",lp->sh->inlineno-(lp->token=='\n'));
882 		t->ar.arcomp = 0;
883+	}
884 	return(t);
885 }
886
887-- snip --
888
889
890######## Errata #008: ########
891A fix for an issue with a Sun Studio warning has been backported:
892The following files have been changed:
893-- snip --
894Index: usr/src/lib/libast/common/path/pathtemp.c
895===================================================================
896--- usr/src/lib/libast/common/path/pathtemp.c	(revision 1822)
897+++ usr/src/lib/libast/common/path/pathtemp.c	(working copy)
898@@ -297,7 +297,7 @@
899 			 */
900
901 			tmp.pid = getpid();
902-			tmp.rng = (uint32_t)tmp.pid * ((uint32_t)time(NiL) ^ (((uint32_t)(&attempt)) >> 3) ^ (((uint32_t)tmp.dir) >> 3));
903+			tmp.rng = (uintptr_t)tmp.pid * ((uintptr_t)time(NiL) ^ (((uintptr_t)(&attempt)) >> 3) ^ (((uintptr_t)tmp.dir) >> 3));
904 			if (!tmp.key)
905 				tmp.key = (tmp.rng >> 16) | ((tmp.rng & 0xffff) << 16);
906 			tmp.rng ^= tmp.key;
907-- snip --
908
909
910######## Errata #009: ########
911A fix for an issue with a typeset -p having problems with compound
912variables and typeset -a -C loosing the -C attribute has been
913backported from ksh93 version "u-":
914-- snip --
915Index: usr/src/lib/libshell/common/bltins/typeset.c
916===================================================================
917--- usr/src/lib/libshell/common/bltins/typeset.c	(revision 1863)
918+++ usr/src/lib/libshell/common/bltins/typeset.c	(working copy)
919@@ -540,7 +540,12 @@
920 					else if(nv_isnull(np))
921 						nv_onattr(np,NV_ARRAY|(comvar?NV_NOFREE:0));
922 					else
923+					{
924+						Namarr_t *ap=nv_arrayptr(np);
925+						if(ap && comvar)
926+							ap->nelem |= ARRAY_TREE;
927 						nv_putsub(np, (char*)0, 0);
928+					}
929 				}
930 				else if(nvflags&NV_ARRAY)
931 				{
932Index: usr/src/lib/libshell/common/sh/nvtree.c
933===================================================================
934--- usr/src/lib/libshell/common/sh/nvtree.c	(revision 1863)
935+++ usr/src/lib/libshell/common/sh/nvtree.c	(working copy)
936@@ -69,6 +69,7 @@
937 static Namval_t *create_tree(Namval_t *np,const char *name,int flag,Namfun_t *dp)
938 {
939 	register Namfun_t *fp=dp;
940+	fp->dsize = 0;
941 	while(fp=fp->next)
942 	{
943 		if(fp->disc && fp->disc->createf)
944@@ -723,7 +724,10 @@
945 			nv_attribute(np,wp->out,"typeset",'=');
946 		nv_outname(wp->out,name,-1);
947 		if((np->nvalue.cp && np->nvalue.cp!=Empty) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE)) || nv_isvtree(np))
948-			sfputc(wp->out,(isarray==2?'\n':'='));
949+		{
950+			if(wp->indent>=0 || isarray!=2)
951+				sfputc(wp->out,(isarray==2?'\n':'='));
952+		}
953 		if(isarray==2)
954 			return;
955 	}
956@@ -1015,7 +1019,7 @@
957  */
958 char *nv_getvtree(register Namval_t *np, Namfun_t *fp)
959 {
960-	int flags=0;
961+	int flags=0, dsize=fp->dsize;
962 	for(; fp && fp->next; fp=fp->next)
963 	{
964 		if(fp->next->disc && (fp->next->disc->getnum || fp->next->disc->getval))
965@@ -1027,6 +1031,8 @@
966 		return(nv_getv(np,fp));
967 	if(flags = nv_isattr(np,NV_EXPORT))
968 		nv_offattr(np,NV_EXPORT);
969+	if(dsize && (flags&NV_EXPORT))
970+		return("()");
971 	return(walk_tree(np,(Namval_t*)0,flags));
972 }
973
974@@ -1083,6 +1089,7 @@
975 		return;
976 	nfp = newof(NIL(void*),Namfun_t,1,0);
977 	nfp->disc = &treedisc;
978+	nfp->dsize = sizeof(Namfun_t);
979 	nv_stack(np, nfp);
980 }
981
982Index: usr/src/lib/libshell/common/sh/array.c
983===================================================================
984--- usr/src/lib/libshell/common/sh/array.c	(revision 1863)
985+++ usr/src/lib/libshell/common/sh/array.c	(working copy)
986@@ -923,9 +923,10 @@
987 			if(array_isbit(aq->bits, dot,ARRAY_CHILD))
988 			{
989 				Namval_t *mp = aq->val[dot].np;
990-				if((aq->header.nelem&ARRAY_NOCHILD) && nv_isvtree(mp))
991+				if((aq->header.nelem&ARRAY_NOCHILD) && nv_isvtree(mp) && !mp->nvfun->dsize)
992 					continue;
993-				nv_putsub(mp,NIL(char*),ARRAY_UNDEF);
994+				if(nv_isarray(mp))
995+					nv_putsub(mp,NIL(char*),ARRAY_UNDEF);
996 			}
997 			return(1);
998 		}
999Index: usr/src/lib/libshell/common/sh/name.c
1000===================================================================
1001--- usr/src/lib/libshell/common/sh/name.c	(revision 1863)
1002+++ usr/src/lib/libshell/common/sh/name.c	(working copy)
1003@@ -538,7 +538,11 @@
1004
1005 				}
1006 				if(!nv_isarray(np) && !typ && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
1007+				{
1008 					nv_setvtree(np);
1009+					if(tp->com.comarg || tp->com.comset)
1010+						np->nvfun->dsize = 0;
1011+				}
1012 #if SHOPT_TYPEDEF
1013 				goto check_type;
1014 #else
1015-- snip --
1016
1017# EOF.
1018