xref: /freebsd/bin/sh/output.c (revision e043f37205ffbde5627ff299ad25cd532f2956f0)
14b88c807SRodney W. Grimes /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
44b88c807SRodney W. Grimes  * Copyright (c) 1991, 1993
54b88c807SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
64b88c807SRodney W. Grimes  *
74b88c807SRodney W. Grimes  * This code is derived from software contributed to Berkeley by
84b88c807SRodney W. Grimes  * Kenneth Almquist.
94b88c807SRodney W. Grimes  *
104b88c807SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
114b88c807SRodney W. Grimes  * modification, are permitted provided that the following conditions
124b88c807SRodney W. Grimes  * are met:
134b88c807SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
144b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
154b88c807SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
164b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
174b88c807SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
18fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
194b88c807SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
204b88c807SRodney W. Grimes  *    without specific prior written permission.
214b88c807SRodney W. Grimes  *
224b88c807SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
234b88c807SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
244b88c807SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
254b88c807SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
264b88c807SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
274b88c807SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
284b88c807SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
294b88c807SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
304b88c807SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
314b88c807SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
324b88c807SRodney W. Grimes  * SUCH DAMAGE.
334b88c807SRodney W. Grimes  */
344b88c807SRodney W. Grimes 
354b88c807SRodney W. Grimes /*
364b88c807SRodney W. Grimes  * Shell output routines.  We use our own output routines because:
374b88c807SRodney W. Grimes  *	When a builtin command is interrupted we have to discard
384b88c807SRodney W. Grimes  *		any pending output.
394b88c807SRodney W. Grimes  *	When a builtin command appears in back quotes, we want to
404b88c807SRodney W. Grimes  *		save the output of the command in a region obtained
414b88c807SRodney W. Grimes  *		via malloc, rather than doing a fork and reading the
424b88c807SRodney W. Grimes  *		output of the command via a pipe.
434b88c807SRodney W. Grimes  */
444b88c807SRodney W. Grimes 
454b88c807SRodney W. Grimes #include <stdio.h>	/* defines BUFSIZ */
46aa9caaf6SPeter Wemm #include <string.h>
47aa9caaf6SPeter Wemm #include <stdarg.h>
48aa9caaf6SPeter Wemm #include <errno.h>
49aa9caaf6SPeter Wemm #include <unistd.h>
50aa9caaf6SPeter Wemm #include <stdlib.h>
5188ef06f3SJilles Tjoelker #include <wchar.h>
5288ef06f3SJilles Tjoelker #include <wctype.h>
53aa9caaf6SPeter Wemm 
544b88c807SRodney W. Grimes #include "shell.h"
554b88c807SRodney W. Grimes #include "syntax.h"
564b88c807SRodney W. Grimes #include "output.h"
574b88c807SRodney W. Grimes #include "memalloc.h"
584b88c807SRodney W. Grimes #include "error.h"
59dee75cf7STim J. Robbins #include "var.h"
604b88c807SRodney W. Grimes 
614b88c807SRodney W. Grimes 
624b88c807SRodney W. Grimes #define OUTBUFSIZ BUFSIZ
636903c683SJilles Tjoelker #define MEM_OUT -2		/* output to dynamically allocated memory */
644b88c807SRodney W. Grimes #define OUTPUT_ERR 01		/* error occurred on output */
654b88c807SRodney W. Grimes 
6688328642SDavid E. O'Brien static int doformat_wr(void *, const char *, int);
674b88c807SRodney W. Grimes 
685183ddf2SJilles Tjoelker struct output output = {NULL, NULL, NULL, OUTBUFSIZ, 1, 0};
695183ddf2SJilles Tjoelker struct output errout = {NULL, NULL, NULL, 256, 2, 0};
70de29cd08SJilles Tjoelker struct output memout = {NULL, NULL, NULL, 64, MEM_OUT, 0};
714b88c807SRodney W. Grimes struct output *out1 = &output;
724b88c807SRodney W. Grimes struct output *out2 = &errout;
734b88c807SRodney W. Grimes 
744b88c807SRodney W. Grimes void
outcslow(int c,struct output * file)75aeb5d065SJilles Tjoelker outcslow(int c, struct output *file)
76aeb5d065SJilles Tjoelker {
77aeb5d065SJilles Tjoelker 	outc(c, file);
78aeb5d065SJilles Tjoelker }
79aeb5d065SJilles Tjoelker 
80aeb5d065SJilles Tjoelker void
out1str(const char * p)815134c3f7SWarner Losh out1str(const char *p)
824b88c807SRodney W. Grimes {
834b88c807SRodney W. Grimes 	outstr(p, out1);
844b88c807SRodney W. Grimes }
854b88c807SRodney W. Grimes 
86e5341cbbSTim J. Robbins void
out1qstr(const char * p)87e5341cbbSTim J. Robbins out1qstr(const char *p)
88e5341cbbSTim J. Robbins {
89e5341cbbSTim J. Robbins 	outqstr(p, out1);
90e5341cbbSTim J. Robbins }
914b88c807SRodney W. Grimes 
924b88c807SRodney W. Grimes void
out2str(const char * p)935134c3f7SWarner Losh out2str(const char *p)
944b88c807SRodney W. Grimes {
954b88c807SRodney W. Grimes 	outstr(p, out2);
964b88c807SRodney W. Grimes }
974b88c807SRodney W. Grimes 
98e5341cbbSTim J. Robbins void
out2qstr(const char * p)99e5341cbbSTim J. Robbins out2qstr(const char *p)
100e5341cbbSTim J. Robbins {
101e5341cbbSTim J. Robbins 	outqstr(p, out2);
102e5341cbbSTim J. Robbins }
1034b88c807SRodney W. Grimes 
1044b88c807SRodney W. Grimes void
outstr(const char * p,struct output * file)1055134c3f7SWarner Losh outstr(const char *p, struct output *file)
1064b88c807SRodney W. Grimes {
107c3f57269SJilles Tjoelker 	outbin(p, strlen(p), file);
1084b88c807SRodney W. Grimes }
1094b88c807SRodney W. Grimes 
11088ef06f3SJilles Tjoelker static void
byteseq(int ch,struct output * file)11188ef06f3SJilles Tjoelker byteseq(int ch, struct output *file)
11288ef06f3SJilles Tjoelker {
11388ef06f3SJilles Tjoelker 	char seq[4];
11488ef06f3SJilles Tjoelker 
11588ef06f3SJilles Tjoelker 	seq[0] = '\\';
11688ef06f3SJilles Tjoelker 	seq[1] = (ch >> 6 & 0x3) + '0';
11788ef06f3SJilles Tjoelker 	seq[2] = (ch >> 3 & 0x7) + '0';
11888ef06f3SJilles Tjoelker 	seq[3] = (ch & 0x7) + '0';
11988ef06f3SJilles Tjoelker 	outbin(seq, 4, file);
12088ef06f3SJilles Tjoelker }
12188ef06f3SJilles Tjoelker 
12288ef06f3SJilles Tjoelker static void
outdqstr(const char * p,struct output * file)12388ef06f3SJilles Tjoelker outdqstr(const char *p, struct output *file)
12488ef06f3SJilles Tjoelker {
12588ef06f3SJilles Tjoelker 	const char *end;
12688ef06f3SJilles Tjoelker 	mbstate_t mbs;
12788ef06f3SJilles Tjoelker 	size_t clen;
12888ef06f3SJilles Tjoelker 	wchar_t wc;
12988ef06f3SJilles Tjoelker 
13088ef06f3SJilles Tjoelker 	memset(&mbs, '\0', sizeof(mbs));
13188ef06f3SJilles Tjoelker 	end = p + strlen(p);
13288ef06f3SJilles Tjoelker 	outstr("$'", file);
13388ef06f3SJilles Tjoelker 	while ((clen = mbrtowc(&wc, p, end - p + 1, &mbs)) != 0) {
13488ef06f3SJilles Tjoelker 		if (clen == (size_t)-2) {
13588ef06f3SJilles Tjoelker 			while (p < end)
13688ef06f3SJilles Tjoelker 				byteseq(*p++, file);
13788ef06f3SJilles Tjoelker 			break;
13888ef06f3SJilles Tjoelker 		}
13988ef06f3SJilles Tjoelker 		if (clen == (size_t)-1) {
14088ef06f3SJilles Tjoelker 			memset(&mbs, '\0', sizeof(mbs));
14188ef06f3SJilles Tjoelker 			byteseq(*p++, file);
14288ef06f3SJilles Tjoelker 			continue;
14388ef06f3SJilles Tjoelker 		}
14488ef06f3SJilles Tjoelker 		if (wc == L'\n')
14588ef06f3SJilles Tjoelker 			outcslow('\n', file), p++;
14688ef06f3SJilles Tjoelker 		else if (wc == L'\r')
14788ef06f3SJilles Tjoelker 			outstr("\\r", file), p++;
14888ef06f3SJilles Tjoelker 		else if (wc == L'\t')
14988ef06f3SJilles Tjoelker 			outstr("\\t", file), p++;
15088ef06f3SJilles Tjoelker 		else if (!iswprint(wc)) {
15188ef06f3SJilles Tjoelker 			for (; clen > 0; clen--)
15288ef06f3SJilles Tjoelker 				byteseq(*p++, file);
15388ef06f3SJilles Tjoelker 		} else {
15488ef06f3SJilles Tjoelker 			if (wc == L'\'' || wc == L'\\')
15588ef06f3SJilles Tjoelker 				outcslow('\\', file);
15688ef06f3SJilles Tjoelker 			outbin(p, clen, file);
15788ef06f3SJilles Tjoelker 			p += clen;
15888ef06f3SJilles Tjoelker 		}
15988ef06f3SJilles Tjoelker 	}
16088ef06f3SJilles Tjoelker 	outcslow('\'', file);
16188ef06f3SJilles Tjoelker }
16288ef06f3SJilles Tjoelker 
163e5341cbbSTim J. Robbins /* Like outstr(), but quote for re-input into the shell. */
164e5341cbbSTim J. Robbins void
outqstr(const char * p,struct output * file)165e5341cbbSTim J. Robbins outqstr(const char *p, struct output *file)
166e5341cbbSTim J. Robbins {
16788ef06f3SJilles Tjoelker 	int i;
168e5341cbbSTim J. Robbins 
1693f0131f6SStefan Farfeleder 	if (p[0] == '\0') {
1703f0131f6SStefan Farfeleder 		outstr("''", file);
1713f0131f6SStefan Farfeleder 		return;
1723f0131f6SStefan Farfeleder 	}
17388ef06f3SJilles Tjoelker 	for (i = 0; p[i] != '\0'; i++) {
17488ef06f3SJilles Tjoelker 		if ((p[i] > '\0' && p[i] < ' ' && p[i] != '\n') ||
17588ef06f3SJilles Tjoelker 		    (p[i] & 0x80) != 0 || p[i] == '\'') {
17688ef06f3SJilles Tjoelker 			outdqstr(p, file);
17788ef06f3SJilles Tjoelker 			return;
17888ef06f3SJilles Tjoelker 		}
17988ef06f3SJilles Tjoelker 	}
18088ef06f3SJilles Tjoelker 
18188ef06f3SJilles Tjoelker 	if (p[strcspn(p, "|&;<>()$`\\\" \n*?[~#=")] == '\0' ||
182e68165a6SJilles Tjoelker 			strcmp(p, "[") == 0) {
183dee75cf7STim J. Robbins 		outstr(p, file);
184dee75cf7STim J. Robbins 		return;
185dee75cf7STim J. Robbins 	}
186dee75cf7STim J. Robbins 
187aeb5d065SJilles Tjoelker 	outcslow('\'', file);
18888ef06f3SJilles Tjoelker 	outstr(p, file);
189aeb5d065SJilles Tjoelker 	outcslow('\'', file);
190e5341cbbSTim J. Robbins }
1914b88c807SRodney W. Grimes 
192c3f57269SJilles Tjoelker void
outbin(const void * data,size_t len,struct output * file)193c3f57269SJilles Tjoelker outbin(const void *data, size_t len, struct output *file)
194c3f57269SJilles Tjoelker {
195c3f57269SJilles Tjoelker 	const char *p;
196c3f57269SJilles Tjoelker 
197c3f57269SJilles Tjoelker 	p = data;
198c3f57269SJilles Tjoelker 	while (len-- > 0)
199c3f57269SJilles Tjoelker 		outc(*p++, file);
200c3f57269SJilles Tjoelker }
201c3f57269SJilles Tjoelker 
2024b88c807SRodney W. Grimes void
emptyoutbuf(struct output * dest)2035134c3f7SWarner Losh emptyoutbuf(struct output *dest)
2044b88c807SRodney W. Grimes {
205de29cd08SJilles Tjoelker 	int offset, newsize;
2064b88c807SRodney W. Grimes 
2076903c683SJilles Tjoelker 	if (dest->buf == NULL) {
2084b88c807SRodney W. Grimes 		INTOFF;
2094b88c807SRodney W. Grimes 		dest->buf = ckmalloc(dest->bufsize);
2104b88c807SRodney W. Grimes 		dest->nextc = dest->buf;
2115183ddf2SJilles Tjoelker 		dest->bufend = dest->buf + dest->bufsize;
2124b88c807SRodney W. Grimes 		INTON;
2134b88c807SRodney W. Grimes 	} else if (dest->fd == MEM_OUT) {
2145183ddf2SJilles Tjoelker 		offset = dest->nextc - dest->buf;
215de29cd08SJilles Tjoelker 		newsize = dest->bufsize << 1;
2164b88c807SRodney W. Grimes 		INTOFF;
217de29cd08SJilles Tjoelker 		dest->buf = ckrealloc(dest->buf, newsize);
218de29cd08SJilles Tjoelker 		dest->bufsize = newsize;
219de29cd08SJilles Tjoelker 		dest->bufend = dest->buf + newsize;
2204b88c807SRodney W. Grimes 		dest->nextc = dest->buf + offset;
2214b88c807SRodney W. Grimes 		INTON;
2224b88c807SRodney W. Grimes 	} else {
2234b88c807SRodney W. Grimes 		flushout(dest);
2244b88c807SRodney W. Grimes 	}
2254b88c807SRodney W. Grimes }
2264b88c807SRodney W. Grimes 
2274b88c807SRodney W. Grimes 
2284b88c807SRodney W. Grimes void
flushall(void)2295134c3f7SWarner Losh flushall(void)
2305134c3f7SWarner Losh {
2314b88c807SRodney W. Grimes 	flushout(&output);
2324b88c807SRodney W. Grimes 	flushout(&errout);
2334b88c807SRodney W. Grimes }
2344b88c807SRodney W. Grimes 
2354b88c807SRodney W. Grimes 
2364b88c807SRodney W. Grimes void
flushout(struct output * dest)2375134c3f7SWarner Losh flushout(struct output *dest)
2384b88c807SRodney W. Grimes {
2394b88c807SRodney W. Grimes 
2404b88c807SRodney W. Grimes 	if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0)
2414b88c807SRodney W. Grimes 		return;
2424b88c807SRodney W. Grimes 	if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0)
2434b88c807SRodney W. Grimes 		dest->flags |= OUTPUT_ERR;
2444b88c807SRodney W. Grimes 	dest->nextc = dest->buf;
2454b88c807SRodney W. Grimes }
2464b88c807SRodney W. Grimes 
2474b88c807SRodney W. Grimes 
2484b88c807SRodney W. Grimes void
freestdout(void)2495134c3f7SWarner Losh freestdout(void)
2505134c3f7SWarner Losh {
25129717eb0SJilles Tjoelker 	output.nextc = output.buf;
2524b88c807SRodney W. Grimes }
2534b88c807SRodney W. Grimes 
2544b88c807SRodney W. Grimes 
255d6d66cfcSJilles Tjoelker int
outiserror(struct output * file)256d6d66cfcSJilles Tjoelker outiserror(struct output *file)
257d6d66cfcSJilles Tjoelker {
258d6d66cfcSJilles Tjoelker 	return (file->flags & OUTPUT_ERR);
259d6d66cfcSJilles Tjoelker }
260d6d66cfcSJilles Tjoelker 
261d6d66cfcSJilles Tjoelker 
262d6d66cfcSJilles Tjoelker void
outclearerror(struct output * file)263d6d66cfcSJilles Tjoelker outclearerror(struct output *file)
264d6d66cfcSJilles Tjoelker {
265d6d66cfcSJilles Tjoelker 	file->flags &= ~OUTPUT_ERR;
266d6d66cfcSJilles Tjoelker }
267d6d66cfcSJilles Tjoelker 
268d6d66cfcSJilles Tjoelker 
2694b88c807SRodney W. Grimes void
outfmt(struct output * file,const char * fmt,...)2705134c3f7SWarner Losh outfmt(struct output *file, const char *fmt, ...)
2715134c3f7SWarner Losh {
2724b88c807SRodney W. Grimes 	va_list ap;
2734b88c807SRodney W. Grimes 
2744b88c807SRodney W. Grimes 	va_start(ap, fmt);
2754b88c807SRodney W. Grimes 	doformat(file, fmt, ap);
2764b88c807SRodney W. Grimes 	va_end(ap);
2774b88c807SRodney W. Grimes }
2784b88c807SRodney W. Grimes 
2794b88c807SRodney W. Grimes 
2804b88c807SRodney W. Grimes void
out1fmt(const char * fmt,...)2815134c3f7SWarner Losh out1fmt(const char *fmt, ...)
2825134c3f7SWarner Losh {
2834b88c807SRodney W. Grimes 	va_list ap;
2844b88c807SRodney W. Grimes 
2854b88c807SRodney W. Grimes 	va_start(ap, fmt);
2864b88c807SRodney W. Grimes 	doformat(out1, fmt, ap);
2874b88c807SRodney W. Grimes 	va_end(ap);
2884b88c807SRodney W. Grimes }
2894b88c807SRodney W. Grimes 
2904b88c807SRodney W. Grimes void
out2fmt_flush(const char * fmt,...)291c6204d4aSJilles Tjoelker out2fmt_flush(const char *fmt, ...)
2925134c3f7SWarner Losh {
2934b88c807SRodney W. Grimes 	va_list ap;
2944b88c807SRodney W. Grimes 
2954b88c807SRodney W. Grimes 	va_start(ap, fmt);
2964b88c807SRodney W. Grimes 	doformat(out2, fmt, ap);
2974b88c807SRodney W. Grimes 	va_end(ap);
2984b88c807SRodney W. Grimes 	flushout(out2);
2994b88c807SRodney W. Grimes }
3004b88c807SRodney W. Grimes 
3014b88c807SRodney W. Grimes void
fmtstr(char * outbuf,int length,const char * fmt,...)3025134c3f7SWarner Losh fmtstr(char *outbuf, int length, const char *fmt, ...)
3035134c3f7SWarner Losh {
3044b88c807SRodney W. Grimes 	va_list ap;
3054b88c807SRodney W. Grimes 
3066903c683SJilles Tjoelker 	INTOFF;
3074b88c807SRodney W. Grimes 	va_start(ap, fmt);
3086903c683SJilles Tjoelker 	vsnprintf(outbuf, length, fmt, ap);
3097e73d40eSTim J. Robbins 	va_end(ap);
3106903c683SJilles Tjoelker 	INTON;
3114b88c807SRodney W. Grimes }
3124b88c807SRodney W. Grimes 
31388328642SDavid E. O'Brien static int
doformat_wr(void * cookie,const char * buf,int len)3147e73d40eSTim J. Robbins doformat_wr(void *cookie, const char *buf, int len)
3157e73d40eSTim J. Robbins {
3167e73d40eSTim J. Robbins 	struct output *o;
3174b88c807SRodney W. Grimes 
3187e73d40eSTim J. Robbins 	o = (struct output *)cookie;
319c3f57269SJilles Tjoelker 	outbin(buf, len, o);
3204b88c807SRodney W. Grimes 
321c3f57269SJilles Tjoelker 	return (len);
3227e73d40eSTim J. Robbins }
3234b88c807SRodney W. Grimes 
3244b88c807SRodney W. Grimes void
doformat(struct output * dest,const char * f,va_list ap)3255134c3f7SWarner Losh doformat(struct output *dest, const char *f, va_list ap)
3264b88c807SRodney W. Grimes {
3277e73d40eSTim J. Robbins 	FILE *fp;
3284b88c807SRodney W. Grimes 
3297e73d40eSTim J. Robbins 	if ((fp = fwopen(dest, doformat_wr)) != NULL) {
3307e73d40eSTim J. Robbins 		vfprintf(fp, f, ap);
3317e73d40eSTim J. Robbins 		fclose(fp);
3324b88c807SRodney W. Grimes 	}
3334b88c807SRodney W. Grimes }
3344b88c807SRodney W. Grimes 
335*94b793c4SJilles Tjoelker FILE *
out1fp(void)336*94b793c4SJilles Tjoelker out1fp(void)
337*94b793c4SJilles Tjoelker {
338*94b793c4SJilles Tjoelker 	return fwopen(out1, doformat_wr);
339*94b793c4SJilles Tjoelker }
340*94b793c4SJilles Tjoelker 
3414b88c807SRodney W. Grimes /*
3424b88c807SRodney W. Grimes  * Version of write which resumes after a signal is caught.
3434b88c807SRodney W. Grimes  */
3444b88c807SRodney W. Grimes 
3454b88c807SRodney W. Grimes int
xwrite(int fd,const char * buf,int nbytes)3462cac6e36SJilles Tjoelker xwrite(int fd, const char *buf, int nbytes)
3474b88c807SRodney W. Grimes {
3484b88c807SRodney W. Grimes 	int ntry;
3494b88c807SRodney W. Grimes 	int i;
3504b88c807SRodney W. Grimes 	int n;
3514b88c807SRodney W. Grimes 
3524b88c807SRodney W. Grimes 	n = nbytes;
3534b88c807SRodney W. Grimes 	ntry = 0;
3544b88c807SRodney W. Grimes 	for (;;) {
3554b88c807SRodney W. Grimes 		i = write(fd, buf, n);
3564b88c807SRodney W. Grimes 		if (i > 0) {
3574b88c807SRodney W. Grimes 			if ((n -= i) <= 0)
3584b88c807SRodney W. Grimes 				return nbytes;
3594b88c807SRodney W. Grimes 			buf += i;
3604b88c807SRodney W. Grimes 			ntry = 0;
3614b88c807SRodney W. Grimes 		} else if (i == 0) {
3624b88c807SRodney W. Grimes 			if (++ntry > 10)
3634b88c807SRodney W. Grimes 				return nbytes - n;
3644b88c807SRodney W. Grimes 		} else if (errno != EINTR) {
3654b88c807SRodney W. Grimes 			return -1;
3664b88c807SRodney W. Grimes 		}
3674b88c807SRodney W. Grimes 	}
3684b88c807SRodney W. Grimes }
369