xref: /onnv-gate/usr/src/cmd/sh/word.c (revision 527:cb400a149efa)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*527Schin 
23*527Schin /*
24*527Schin  * Copyright 2000 Sun Microsystems, Inc.  All rights reserved.
25*527Schin  * Use is subject to license terms.
26*527Schin  */
27*527Schin 
280Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
290Sstevel@tonic-gate /*	  All Rights Reserved  	*/
300Sstevel@tonic-gate 
31*527Schin #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  * UNIX shell
340Sstevel@tonic-gate  */
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include	"defs.h"
370Sstevel@tonic-gate #include	"sym.h"
380Sstevel@tonic-gate #include	<errno.h>
390Sstevel@tonic-gate #include	<fcntl.h>
400Sstevel@tonic-gate 
410Sstevel@tonic-gate static int	readb(struct fileblk *, int, int);
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /* ========	character handling for command lines	======== */
440Sstevel@tonic-gate 
45*527Schin int
word(void)46*527Schin word(void)
470Sstevel@tonic-gate {
48*527Schin 	unsigned int	c, d, cc;
490Sstevel@tonic-gate 	struct argnod	*arg = (struct argnod *)locstak();
50*527Schin 	unsigned char	*argp = arg->argval;
510Sstevel@tonic-gate 	unsigned char	*oldargp;
520Sstevel@tonic-gate 	int		alpha = 1;
530Sstevel@tonic-gate 	unsigned char *pc;
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	wdnum = 0;
560Sstevel@tonic-gate 	wdset = 0;
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 	while (1)
590Sstevel@tonic-gate 	{
600Sstevel@tonic-gate 		while (c = nextwc(), space(c))		/* skipc() */
610Sstevel@tonic-gate 			;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 		if (c == COMCHAR)
640Sstevel@tonic-gate 		{
650Sstevel@tonic-gate 			while ((c = readwc()) != NL && c != EOF);
660Sstevel@tonic-gate 			peekc = c;
670Sstevel@tonic-gate 		}
680Sstevel@tonic-gate 		else
690Sstevel@tonic-gate 		{
700Sstevel@tonic-gate 			break;	/* out of comment - white space loop */
710Sstevel@tonic-gate 		}
720Sstevel@tonic-gate 	}
730Sstevel@tonic-gate 	if (!eofmeta(c))
740Sstevel@tonic-gate 	{
750Sstevel@tonic-gate 		do
760Sstevel@tonic-gate 		{
770Sstevel@tonic-gate 			if (c == LITERAL)
780Sstevel@tonic-gate 			{
790Sstevel@tonic-gate 				oldargp = argp;
800Sstevel@tonic-gate 				while ((c = readwc()) && c != LITERAL){
810Sstevel@tonic-gate 					/*
820Sstevel@tonic-gate 					 * quote each character within
830Sstevel@tonic-gate 					 * single quotes
840Sstevel@tonic-gate 					 */
850Sstevel@tonic-gate 					pc = readw(c);
860Sstevel@tonic-gate 					if (argp >= brkend)
870Sstevel@tonic-gate 						growstak(argp);
880Sstevel@tonic-gate 					*argp++='\\';
890Sstevel@tonic-gate 				/* Pick up rest of multibyte character */
900Sstevel@tonic-gate 					if (c == NL)
910Sstevel@tonic-gate 						chkpr();
920Sstevel@tonic-gate 					while (c = *pc++) {
930Sstevel@tonic-gate 						if (argp >= brkend)
940Sstevel@tonic-gate 							growstak(argp);
950Sstevel@tonic-gate 						*argp++ = (unsigned char)c;
960Sstevel@tonic-gate 					}
970Sstevel@tonic-gate 				}
980Sstevel@tonic-gate 				if (argp == oldargp) { /* null argument - '' */
990Sstevel@tonic-gate 				/*
1000Sstevel@tonic-gate 				 * Word will be represented by quoted null
1010Sstevel@tonic-gate 				 * in macro.c if necessary
1020Sstevel@tonic-gate 				 */
1030Sstevel@tonic-gate 					if (argp >= brkend)
1040Sstevel@tonic-gate 						growstak(argp);
1050Sstevel@tonic-gate 					*argp++ = '"';
1060Sstevel@tonic-gate 					if (argp >= brkend)
1070Sstevel@tonic-gate 						growstak(argp);
1080Sstevel@tonic-gate 					*argp++ = '"';
1090Sstevel@tonic-gate 				}
1100Sstevel@tonic-gate 			}
1110Sstevel@tonic-gate 			else
1120Sstevel@tonic-gate 			{
1130Sstevel@tonic-gate 				if (c == 0) {
1140Sstevel@tonic-gate 					if (argp >= brkend)
1150Sstevel@tonic-gate 						growstak(argp);
1160Sstevel@tonic-gate 					*argp++ = 0;
1170Sstevel@tonic-gate 				} else {
1180Sstevel@tonic-gate 					pc = readw(c);
1190Sstevel@tonic-gate 					while (*pc) {
1200Sstevel@tonic-gate 						if (argp >= brkend)
1210Sstevel@tonic-gate 							growstak(argp);
1220Sstevel@tonic-gate 						*argp++ = *pc++;
1230Sstevel@tonic-gate 					}
1240Sstevel@tonic-gate 				}
1250Sstevel@tonic-gate 				if (c == '\\') {
1260Sstevel@tonic-gate 					if ((cc = readwc()) == 0) {
1270Sstevel@tonic-gate 						if (argp >= brkend)
1280Sstevel@tonic-gate 							growstak(argp);
1290Sstevel@tonic-gate 						*argp++ = 0;
1300Sstevel@tonic-gate 					} else {
1310Sstevel@tonic-gate 						pc = readw(cc);
1320Sstevel@tonic-gate 						while (*pc) {
1330Sstevel@tonic-gate 							if (argp >= brkend)
1340Sstevel@tonic-gate 								growstak(argp);
1350Sstevel@tonic-gate 							*argp++ = *pc++;
1360Sstevel@tonic-gate 						}
1370Sstevel@tonic-gate 					}
1380Sstevel@tonic-gate 				}
1390Sstevel@tonic-gate 				if (c == '=')
1400Sstevel@tonic-gate 					wdset |= alpha;
1410Sstevel@tonic-gate 				if (!alphanum(c))
1420Sstevel@tonic-gate 					alpha = 0;
1430Sstevel@tonic-gate 				if (qotchar(c))
1440Sstevel@tonic-gate 				{
1450Sstevel@tonic-gate 					d = c;
1460Sstevel@tonic-gate 					for (;;)
1470Sstevel@tonic-gate 					{
1480Sstevel@tonic-gate 						if ((c = nextwc()) == 0) {
1490Sstevel@tonic-gate 							if (argp >= brkend)
1500Sstevel@tonic-gate 								growstak(argp);
1510Sstevel@tonic-gate 							*argp++ = 0;
1520Sstevel@tonic-gate 						} else {
1530Sstevel@tonic-gate 							pc = readw(c);
1540Sstevel@tonic-gate 							while (*pc) {
1550Sstevel@tonic-gate 								if (argp >= brkend)
1560Sstevel@tonic-gate 									growstak(argp);
1570Sstevel@tonic-gate 								*argp++ = *pc++;
1580Sstevel@tonic-gate 							}
1590Sstevel@tonic-gate 						}
1600Sstevel@tonic-gate 						if (c == 0 || c == d)
1610Sstevel@tonic-gate 							break;
1620Sstevel@tonic-gate 						if (c == NL)
1630Sstevel@tonic-gate 							chkpr();
1640Sstevel@tonic-gate 						/*
1650Sstevel@tonic-gate 						 * don't interpret quoted
1660Sstevel@tonic-gate 						 * characters
1670Sstevel@tonic-gate 						 */
1680Sstevel@tonic-gate 						if (c == '\\') {
1690Sstevel@tonic-gate 							if ((cc = readwc()) == 0) {
1700Sstevel@tonic-gate 								if (argp >= brkend)
1710Sstevel@tonic-gate 									growstak(argp);
1720Sstevel@tonic-gate 								*argp++ = 0;
1730Sstevel@tonic-gate 							} else {
1740Sstevel@tonic-gate 								pc = readw(cc);
1750Sstevel@tonic-gate 								while (*pc) {
1760Sstevel@tonic-gate 									if (argp >= brkend)
1770Sstevel@tonic-gate 										growstak(argp);
1780Sstevel@tonic-gate 									*argp++ = *pc++;
1790Sstevel@tonic-gate 								}
1800Sstevel@tonic-gate 							}
1810Sstevel@tonic-gate 						}
1820Sstevel@tonic-gate 					}
1830Sstevel@tonic-gate 				}
1840Sstevel@tonic-gate 			}
1850Sstevel@tonic-gate 		} while ((c = nextwc(), !eofmeta(c)));
1860Sstevel@tonic-gate 		argp = endstak(argp);
1870Sstevel@tonic-gate 		if (!letter(arg->argval[0]))
1880Sstevel@tonic-gate 			wdset = 0;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 		peekn = c | MARK;
1910Sstevel@tonic-gate 		if (arg->argval[1] == 0 &&
1920Sstevel@tonic-gate 		    (d = arg->argval[0], digit(d)) &&
1930Sstevel@tonic-gate 		    (c == '>' || c == '<'))
1940Sstevel@tonic-gate 		{
1950Sstevel@tonic-gate 			word();
1960Sstevel@tonic-gate 			wdnum = d - '0';
1970Sstevel@tonic-gate 		}else{ /* check for reserved words */
1980Sstevel@tonic-gate 			if (reserv == FALSE ||
1990Sstevel@tonic-gate 			    (wdval = syslook(arg->argval,
2000Sstevel@tonic-gate 					reserved, no_reserved)) == 0) {
2010Sstevel@tonic-gate 				wdval = 0;
2020Sstevel@tonic-gate 			}
2030Sstevel@tonic-gate 			/* set arg for reserved words too */
2040Sstevel@tonic-gate 			wdarg = arg;
2050Sstevel@tonic-gate 		}
2060Sstevel@tonic-gate 	}else if (dipchar(c)){
2070Sstevel@tonic-gate 		if ((d = nextwc()) == c)
2080Sstevel@tonic-gate 		{
2090Sstevel@tonic-gate 			wdval = c | SYMREP;
2100Sstevel@tonic-gate 			if (c == '<')
2110Sstevel@tonic-gate 			{
2120Sstevel@tonic-gate 				if ((d = nextwc()) == '-')
2130Sstevel@tonic-gate 					wdnum |= IOSTRIP;
2140Sstevel@tonic-gate 				else
2150Sstevel@tonic-gate 					peekn = d | MARK;
2160Sstevel@tonic-gate 			}
2170Sstevel@tonic-gate 		}
2180Sstevel@tonic-gate 		else
2190Sstevel@tonic-gate 		{
2200Sstevel@tonic-gate 			peekn = d | MARK;
2210Sstevel@tonic-gate 			wdval = c;
2220Sstevel@tonic-gate 		}
2230Sstevel@tonic-gate 	}
2240Sstevel@tonic-gate 	else
2250Sstevel@tonic-gate 	{
2260Sstevel@tonic-gate 		if ((wdval = c) == EOF)
2270Sstevel@tonic-gate 			wdval = EOFSYM;
2280Sstevel@tonic-gate 		if (iopend && eolchar(c))
2290Sstevel@tonic-gate 		{
2300Sstevel@tonic-gate 			struct ionod *tmp_iopend;
2310Sstevel@tonic-gate 			tmp_iopend = iopend;
2320Sstevel@tonic-gate 			iopend = 0;
2330Sstevel@tonic-gate 			copy(tmp_iopend);
2340Sstevel@tonic-gate 		}
2350Sstevel@tonic-gate 	}
2360Sstevel@tonic-gate 	reserv = FALSE;
2370Sstevel@tonic-gate 	return (wdval);
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate 
skipwc()2400Sstevel@tonic-gate unsigned int skipwc()
2410Sstevel@tonic-gate {
242*527Schin 	unsigned int c;
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate 	while (c = nextwc(), space(c))
2450Sstevel@tonic-gate 		;
2460Sstevel@tonic-gate 	return (c);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate 
nextwc()2490Sstevel@tonic-gate unsigned int nextwc()
2500Sstevel@tonic-gate {
251*527Schin 	unsigned int	c, d;
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate retry:
2540Sstevel@tonic-gate 	if ((d = readwc()) == ESCAPE) {
2550Sstevel@tonic-gate 		if ((c = readwc()) == NL) {
2560Sstevel@tonic-gate 			chkpr();
2570Sstevel@tonic-gate 			goto retry;
2580Sstevel@tonic-gate 		}
2590Sstevel@tonic-gate 		peekc = c | MARK;
2600Sstevel@tonic-gate 	}
2610Sstevel@tonic-gate 	return (d);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate 
readw(d)2640Sstevel@tonic-gate unsigned char *readw(d)
2650Sstevel@tonic-gate wchar_t	d;
2660Sstevel@tonic-gate {
2670Sstevel@tonic-gate 	static unsigned char c[MULTI_BYTE_MAX + 1];
2680Sstevel@tonic-gate 	int length;
2690Sstevel@tonic-gate 	wchar_t l;
2700Sstevel@tonic-gate 	if (isascii(d)) {
2710Sstevel@tonic-gate 		c[0] = d;
2720Sstevel@tonic-gate 		c[1] = '\0';
2730Sstevel@tonic-gate 		return (c);
2740Sstevel@tonic-gate 	}
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 	length = wctomb((char *)c, d);
2770Sstevel@tonic-gate 	if (length <= 0) {
2780Sstevel@tonic-gate 		c[0] = (unsigned char)d;
2790Sstevel@tonic-gate 		length = 1;
2800Sstevel@tonic-gate 	}
2810Sstevel@tonic-gate 	c[length] = '\0';
2820Sstevel@tonic-gate 	return (c);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate unsigned int
readwc()2860Sstevel@tonic-gate readwc()
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate 	wchar_t	c;
2890Sstevel@tonic-gate 	int	len;
2900Sstevel@tonic-gate 	struct fileblk	*f;
2910Sstevel@tonic-gate 	int	mbmax = MB_CUR_MAX;
2920Sstevel@tonic-gate 	int	i, mlen;
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 	if (peekn) {
2950Sstevel@tonic-gate 		c = peekn & 0x7fffffff;
2960Sstevel@tonic-gate 		peekn = 0;
2970Sstevel@tonic-gate 		return (c);
2980Sstevel@tonic-gate 	}
2990Sstevel@tonic-gate 	if (peekc) {
3000Sstevel@tonic-gate 		c = peekc & 0x7fffffff;
3010Sstevel@tonic-gate 		peekc = 0;
3020Sstevel@tonic-gate 		return (c);
3030Sstevel@tonic-gate 	}
3040Sstevel@tonic-gate 	f = standin;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate retry:
3070Sstevel@tonic-gate 	if (f->fend > f->fnxt) {
3080Sstevel@tonic-gate 		/*
3090Sstevel@tonic-gate 		 * something in buffer
3100Sstevel@tonic-gate 		 */
3110Sstevel@tonic-gate 		if (*f->fnxt == 0) {
3120Sstevel@tonic-gate 			f->fnxt++;
3130Sstevel@tonic-gate 			f->nxtoff++;
3140Sstevel@tonic-gate 			if (f->feval == 0)
3150Sstevel@tonic-gate 				goto retry;	/* = c = readc(); */
3160Sstevel@tonic-gate 			if (estabf(*f->feval++))
3170Sstevel@tonic-gate 				c = EOF;
3180Sstevel@tonic-gate 			else
3190Sstevel@tonic-gate 				c = SPACE;
3200Sstevel@tonic-gate 			if (flags & readpr && standin->fstak == 0)
3210Sstevel@tonic-gate 				prc(c);
3220Sstevel@tonic-gate 			if (c == NL)
3230Sstevel@tonic-gate 				f->flin++;
3240Sstevel@tonic-gate 			return (c);
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 		if (isascii(c = (unsigned char)*f->fnxt)) {
3280Sstevel@tonic-gate 			f->fnxt++;
3290Sstevel@tonic-gate 			f->nxtoff++;
3300Sstevel@tonic-gate 			if (flags & readpr && standin->fstak == 0)
3310Sstevel@tonic-gate 				prc(c);
3320Sstevel@tonic-gate 			if (c == NL)
3330Sstevel@tonic-gate 				f->flin++;
3340Sstevel@tonic-gate 			return (c);
3350Sstevel@tonic-gate 		}
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		for (i = 1; i <= mbmax; i++) {
3380Sstevel@tonic-gate 			int	rest;
3390Sstevel@tonic-gate 			if ((rest = f->fend - f->fnxt) < i) {
3400Sstevel@tonic-gate 				/*
3410Sstevel@tonic-gate 				 * not enough bytes available
3420Sstevel@tonic-gate 				 * f->fsiz could be BUFFERSIZE or 1
3430Sstevel@tonic-gate 				 * since mbmax is enough smaller than BUFFERSIZE,
3440Sstevel@tonic-gate 				 * this loop won't overrun the f->fbuf buffer.
3450Sstevel@tonic-gate 				 */
3460Sstevel@tonic-gate 				len = readb(f,
3470Sstevel@tonic-gate 					(f->fsiz == 1) ? 1 : (f->fsiz - rest),
3480Sstevel@tonic-gate 					rest);
3490Sstevel@tonic-gate 				if (len == 0)
3500Sstevel@tonic-gate 					break;
3510Sstevel@tonic-gate 			}
3520Sstevel@tonic-gate 			mlen = mbtowc(&c, (char *)f->fnxt, i);
3530Sstevel@tonic-gate 			if (mlen > 0)
3540Sstevel@tonic-gate 				break;
3550Sstevel@tonic-gate 		}
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 		if (i > mbmax) {
3580Sstevel@tonic-gate 			/*
3590Sstevel@tonic-gate 			 * enough bytes available but cannot be converted to
3600Sstevel@tonic-gate 			 * a valid wchar.
3610Sstevel@tonic-gate 			 */
3620Sstevel@tonic-gate 			c = (unsigned char)*f->fnxt;
3630Sstevel@tonic-gate 			mlen = 1;
3640Sstevel@tonic-gate 		}
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 		f->fnxt += mlen;
3670Sstevel@tonic-gate 		f->nxtoff += mlen;
3680Sstevel@tonic-gate 		if (flags & readpr && standin->fstak == 0)
3690Sstevel@tonic-gate 			prwc(c);
3700Sstevel@tonic-gate 		if (c == NL)
3710Sstevel@tonic-gate 			f->flin++;
3720Sstevel@tonic-gate 		return (c);
3730Sstevel@tonic-gate 	}
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate 	if (f->feof || f->fdes < 0){
3760Sstevel@tonic-gate 		c = EOF;
3770Sstevel@tonic-gate 		f->feof++;
3780Sstevel@tonic-gate 		return (c);
3790Sstevel@tonic-gate 	}
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate 	if (readb(f, f->fsiz, 0) <= 0){
3820Sstevel@tonic-gate 		if (f->fdes != input || !isatty(input)) {
3830Sstevel@tonic-gate 			close(f->fdes);
3840Sstevel@tonic-gate 			f->fdes = -1;
3850Sstevel@tonic-gate 		}
3860Sstevel@tonic-gate 		f->feof++;
3870Sstevel@tonic-gate 		c = EOF;
3880Sstevel@tonic-gate 		return (c);
3890Sstevel@tonic-gate 	}
3900Sstevel@tonic-gate 	goto retry;
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate static int
readb(struct fileblk * f,int toread,int rest)3940Sstevel@tonic-gate readb(struct fileblk *f, int toread, int rest)
3950Sstevel@tonic-gate {
3960Sstevel@tonic-gate 	int	len;
3970Sstevel@tonic-gate 	int	fflags;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	if (rest) {
4000Sstevel@tonic-gate 		/*
4010Sstevel@tonic-gate 		 * copies the remaining 'rest' bytes from f->fnxt
4020Sstevel@tonic-gate 		 * to f->fbuf
4030Sstevel@tonic-gate 		 */
4040Sstevel@tonic-gate 		(void) memcpy(f->fbuf, f->fnxt, rest);
4050Sstevel@tonic-gate 		f->fnxt = f->fbuf;
4060Sstevel@tonic-gate 		f->fend = f->fnxt + rest;
4070Sstevel@tonic-gate 		f->nxtoff = 0;
4080Sstevel@tonic-gate 		f->endoff = rest;
4090Sstevel@tonic-gate 		if (f->fbuf[rest - 1] == '\n') {
4100Sstevel@tonic-gate 			/*
4110Sstevel@tonic-gate 			 * if '\n' found, it should be
4120Sstevel@tonic-gate 			 * a bondary of multibyte char.
4130Sstevel@tonic-gate 			 */
4140Sstevel@tonic-gate 			return (rest);
4150Sstevel@tonic-gate 		}
4160Sstevel@tonic-gate 	}
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate retry:
4190Sstevel@tonic-gate 	do {
4200Sstevel@tonic-gate 		if (trapnote & SIGSET) {
4210Sstevel@tonic-gate 			newline();
4220Sstevel@tonic-gate 			sigchk();
4230Sstevel@tonic-gate 		} else if ((trapnote & TRAPSET) && (rwait > 0)) {
4240Sstevel@tonic-gate 			newline();
4250Sstevel@tonic-gate 			chktrap();
4260Sstevel@tonic-gate 			clearup();
4270Sstevel@tonic-gate 		}
4280Sstevel@tonic-gate 	} while ((len = read(f->fdes, f->fbuf + rest, toread)) < 0 && trapnote);
4290Sstevel@tonic-gate 	/*
4300Sstevel@tonic-gate 	 * if child sets O_NDELAY or O_NONBLOCK on stdin
4310Sstevel@tonic-gate 	 * and exited then turn the modes off and retry
4320Sstevel@tonic-gate 	 */
4330Sstevel@tonic-gate 	if (len == 0) {
4340Sstevel@tonic-gate 		if (((flags & intflg) ||
4350Sstevel@tonic-gate 		    ((flags & oneflg) == 0 && isatty(input) &&
4360Sstevel@tonic-gate 		    (flags & stdflg))) &&
4370Sstevel@tonic-gate 		    ((fflags = fcntl(f->fdes, F_GETFL, 0)) & O_NDELAY)) {
4380Sstevel@tonic-gate 			fflags &= ~O_NDELAY;
4390Sstevel@tonic-gate 			fcntl(f->fdes, F_SETFL, fflags);
4400Sstevel@tonic-gate 			goto retry;
4410Sstevel@tonic-gate 		}
4420Sstevel@tonic-gate 	} else if (len < 0) {
4430Sstevel@tonic-gate 		if (errno == EAGAIN) {
4440Sstevel@tonic-gate 			fflags = fcntl(f->fdes, F_GETFL, 0);
4450Sstevel@tonic-gate 			fflags &= ~O_NONBLOCK;
4460Sstevel@tonic-gate 			fcntl(f->fdes, F_SETFL, fflags);
4470Sstevel@tonic-gate 			goto retry;
4480Sstevel@tonic-gate 		}
4490Sstevel@tonic-gate 		len = 0;
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 	f->fnxt = f->fbuf;
4520Sstevel@tonic-gate 	f->fend = f->fnxt + (len + rest);
4530Sstevel@tonic-gate 	f->nxtoff = 0;
4540Sstevel@tonic-gate 	f->endoff = len + rest;
4550Sstevel@tonic-gate 	return (len + rest);
4560Sstevel@tonic-gate }
457