xref: /illumos-gate/usr/src/stand/lib/sa/stdio.c (revision 7c478bd95313f5f23a4c958a745db2134aa0324)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  *
26*7c478bd9Sstevel@tonic-gate  * "buffered" i/o functions for the standalone environment. (ugh).
27*7c478bd9Sstevel@tonic-gate  */
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/promif.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/varargs.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/bootvfs.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/salib.h>
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate enum {
38*7c478bd9Sstevel@tonic-gate 	F_OPEN		= 0x01,
39*7c478bd9Sstevel@tonic-gate 	F_ERROR		= 0x02,
40*7c478bd9Sstevel@tonic-gate 	F_SEEKABLE	= 0x04
41*7c478bd9Sstevel@tonic-gate };
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate FILE	__iob[_NFILE] = {
44*7c478bd9Sstevel@tonic-gate 	{ F_OPEN, 0, 0, 0, "stdin"	},
45*7c478bd9Sstevel@tonic-gate 	{ F_OPEN, 1, 0, 0, "stdout"	},
46*7c478bd9Sstevel@tonic-gate 	{ F_OPEN, 2, 0, 0, "stderr"	}
47*7c478bd9Sstevel@tonic-gate };
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate static boolean_t
50*7c478bd9Sstevel@tonic-gate fcheck(FILE *stream, int flags)
51*7c478bd9Sstevel@tonic-gate {
52*7c478bd9Sstevel@tonic-gate 	errno = 0;
53*7c478bd9Sstevel@tonic-gate 	if ((stream->_flag & flags) != flags) {
54*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
55*7c478bd9Sstevel@tonic-gate 		return (B_FALSE);
56*7c478bd9Sstevel@tonic-gate 	}
57*7c478bd9Sstevel@tonic-gate 	return (B_TRUE);
58*7c478bd9Sstevel@tonic-gate }
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate int
61*7c478bd9Sstevel@tonic-gate fclose(FILE *stream)
62*7c478bd9Sstevel@tonic-gate {
63*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
64*7c478bd9Sstevel@tonic-gate 		return (EOF);
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	(void) close(stream->_file);
67*7c478bd9Sstevel@tonic-gate 	stream->_flag = 0;
68*7c478bd9Sstevel@tonic-gate 	stream->_file = -1;
69*7c478bd9Sstevel@tonic-gate 	stream->_name[0] = '\0';
70*7c478bd9Sstevel@tonic-gate 	return (0);
71*7c478bd9Sstevel@tonic-gate }
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate int
74*7c478bd9Sstevel@tonic-gate feof(FILE *stream)
75*7c478bd9Sstevel@tonic-gate {
76*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
77*7c478bd9Sstevel@tonic-gate 		return (0);
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	return (stream->_len == stream->_offset);
80*7c478bd9Sstevel@tonic-gate }
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate int
83*7c478bd9Sstevel@tonic-gate ferror(FILE *stream)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
86*7c478bd9Sstevel@tonic-gate 		return (0);
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate 	return ((stream->_flag & F_ERROR) != 0);
89*7c478bd9Sstevel@tonic-gate }
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate void
92*7c478bd9Sstevel@tonic-gate clearerr(FILE *stream)
93*7c478bd9Sstevel@tonic-gate {
94*7c478bd9Sstevel@tonic-gate 	stream->_flag &= ~F_ERROR;
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate int
98*7c478bd9Sstevel@tonic-gate fflush(FILE *stream)
99*7c478bd9Sstevel@tonic-gate {
100*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
101*7c478bd9Sstevel@tonic-gate 		return (EOF);
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	/* Currently, a nop */
104*7c478bd9Sstevel@tonic-gate 	return (0);
105*7c478bd9Sstevel@tonic-gate }
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate char *
108*7c478bd9Sstevel@tonic-gate fgets(char *s, int n, FILE *stream)
109*7c478bd9Sstevel@tonic-gate {
110*7c478bd9Sstevel@tonic-gate 	int	bytes;
111*7c478bd9Sstevel@tonic-gate 	ssize_t	cnt;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
114*7c478bd9Sstevel@tonic-gate 		return (NULL);
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	for (bytes = 0; bytes < (n - 1); ++bytes) {
117*7c478bd9Sstevel@tonic-gate 		cnt = read(stream->_file, &s[bytes], 1);
118*7c478bd9Sstevel@tonic-gate 		if (cnt < 0) {
119*7c478bd9Sstevel@tonic-gate 			if (bytes != 0) {
120*7c478bd9Sstevel@tonic-gate 				s[bytes] = '\0';
121*7c478bd9Sstevel@tonic-gate 				return (s);
122*7c478bd9Sstevel@tonic-gate 			} else {
123*7c478bd9Sstevel@tonic-gate 				stream->_flag |= F_ERROR;
124*7c478bd9Sstevel@tonic-gate 				return (NULL);
125*7c478bd9Sstevel@tonic-gate 			}
126*7c478bd9Sstevel@tonic-gate 		} else if (cnt == 0) {
127*7c478bd9Sstevel@tonic-gate 			/* EOF */
128*7c478bd9Sstevel@tonic-gate 			if (bytes != 0) {
129*7c478bd9Sstevel@tonic-gate 				s[bytes] = '\0';
130*7c478bd9Sstevel@tonic-gate 				return (s);
131*7c478bd9Sstevel@tonic-gate 			} else
132*7c478bd9Sstevel@tonic-gate 				return (NULL);
133*7c478bd9Sstevel@tonic-gate 		} else {
134*7c478bd9Sstevel@tonic-gate 			stream->_offset++;
135*7c478bd9Sstevel@tonic-gate 			if (s[bytes] == '\n') {
136*7c478bd9Sstevel@tonic-gate 				s[bytes + 1] = '\0';
137*7c478bd9Sstevel@tonic-gate 				return (s);
138*7c478bd9Sstevel@tonic-gate 			}
139*7c478bd9Sstevel@tonic-gate 		}
140*7c478bd9Sstevel@tonic-gate 	}
141*7c478bd9Sstevel@tonic-gate 	s[bytes] = '\0';
142*7c478bd9Sstevel@tonic-gate 	return (s);
143*7c478bd9Sstevel@tonic-gate }
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate /*
146*7c478bd9Sstevel@tonic-gate  * We currently only support read-only ("r" mode) opens and unbuffered I/O.
147*7c478bd9Sstevel@tonic-gate  */
148*7c478bd9Sstevel@tonic-gate FILE *
149*7c478bd9Sstevel@tonic-gate fopen(const char *filename, const char *mode)
150*7c478bd9Sstevel@tonic-gate {
151*7c478bd9Sstevel@tonic-gate 	FILE		*stream;
152*7c478bd9Sstevel@tonic-gate 	const char	*t;
153*7c478bd9Sstevel@tonic-gate 	int		fd, i;
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 	errno = 0;
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 	/*
158*7c478bd9Sstevel@tonic-gate 	 * Make sure we have a filesystem underneath us before even trying.
159*7c478bd9Sstevel@tonic-gate 	 */
160*7c478bd9Sstevel@tonic-gate 	if (get_default_fs() == NULL)
161*7c478bd9Sstevel@tonic-gate 		return (NULL);
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 	for (t = mode; t != NULL && *t != '\0'; t++) {
164*7c478bd9Sstevel@tonic-gate 		switch (*t) {
165*7c478bd9Sstevel@tonic-gate 		case 'b':
166*7c478bd9Sstevel@tonic-gate 			/* We ignore this a'la ISO C standard conformance */
167*7c478bd9Sstevel@tonic-gate 			break;
168*7c478bd9Sstevel@tonic-gate 		case 'r':
169*7c478bd9Sstevel@tonic-gate 			/* We ignore this because we always open for reading */
170*7c478bd9Sstevel@tonic-gate 			break;
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 		case 'a':
173*7c478bd9Sstevel@tonic-gate 		case 'w':
174*7c478bd9Sstevel@tonic-gate 		case '+':
175*7c478bd9Sstevel@tonic-gate 			errno = EROFS;
176*7c478bd9Sstevel@tonic-gate 			return (NULL);
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 		default:
179*7c478bd9Sstevel@tonic-gate 			errno = EINVAL;
180*7c478bd9Sstevel@tonic-gate 			return (NULL);
181*7c478bd9Sstevel@tonic-gate 		}
182*7c478bd9Sstevel@tonic-gate 	}
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < _NFILE; i++) {
185*7c478bd9Sstevel@tonic-gate 		stream = &__iob[i];
186*7c478bd9Sstevel@tonic-gate 		if ((stream->_flag & F_OPEN) == 0) {
187*7c478bd9Sstevel@tonic-gate 			fd = open(filename, O_RDONLY);
188*7c478bd9Sstevel@tonic-gate 			if (fd < 0)
189*7c478bd9Sstevel@tonic-gate 				return (NULL);
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 			stream->_file = fd;
192*7c478bd9Sstevel@tonic-gate 			stream->_flag |= F_OPEN;
193*7c478bd9Sstevel@tonic-gate 			(void) strlcpy(stream->_name, filename,
194*7c478bd9Sstevel@tonic-gate 			    sizeof (stream->_name));
195*7c478bd9Sstevel@tonic-gate 			return (stream);
196*7c478bd9Sstevel@tonic-gate 		}
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	errno = EMFILE;
200*7c478bd9Sstevel@tonic-gate 	return (NULL);
201*7c478bd9Sstevel@tonic-gate }
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate /* PRINTFLIKE1 */
204*7c478bd9Sstevel@tonic-gate void
205*7c478bd9Sstevel@tonic-gate printf(const char *fmt, ...)
206*7c478bd9Sstevel@tonic-gate {
207*7c478bd9Sstevel@tonic-gate 	va_list adx;
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	va_start(adx, fmt);
210*7c478bd9Sstevel@tonic-gate 	prom_vprintf(fmt, adx);
211*7c478bd9Sstevel@tonic-gate 	va_end(adx);
212*7c478bd9Sstevel@tonic-gate }
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate /*
215*7c478bd9Sstevel@tonic-gate  * Only writing to stderr or stdout is permitted.
216*7c478bd9Sstevel@tonic-gate  */
217*7c478bd9Sstevel@tonic-gate /* PRINTFLIKE2 */
218*7c478bd9Sstevel@tonic-gate int
219*7c478bd9Sstevel@tonic-gate fprintf(FILE *stream, const char *format, ...)
220*7c478bd9Sstevel@tonic-gate {
221*7c478bd9Sstevel@tonic-gate 	int	nwritten;
222*7c478bd9Sstevel@tonic-gate 	va_list	va;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
225*7c478bd9Sstevel@tonic-gate 		return (-1);
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 	/*
228*7c478bd9Sstevel@tonic-gate 	 * Since fopen() doesn't return writable streams, the only valid
229*7c478bd9Sstevel@tonic-gate 	 * writable streams are stdout and stderr.
230*7c478bd9Sstevel@tonic-gate 	 */
231*7c478bd9Sstevel@tonic-gate 	if (stream != stdout && stream != stderr) {
232*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
233*7c478bd9Sstevel@tonic-gate 		return (-1);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 	va_start(va, format);
237*7c478bd9Sstevel@tonic-gate 	printf(format, va);
238*7c478bd9Sstevel@tonic-gate 	va_end(va);
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 	va_start(va, format);
241*7c478bd9Sstevel@tonic-gate 	nwritten = vsnprintf(NULL, 0, format, va);
242*7c478bd9Sstevel@tonic-gate 	va_end(va);
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	return (nwritten);
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate size_t
248*7c478bd9Sstevel@tonic-gate fread(void *ptr, size_t size, size_t nitems, FILE *stream)
249*7c478bd9Sstevel@tonic-gate {
250*7c478bd9Sstevel@tonic-gate 	size_t	items;
251*7c478bd9Sstevel@tonic-gate 	ssize_t	bytes, totbytes = 0;
252*7c478bd9Sstevel@tonic-gate 	char	*strp = ptr;
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
255*7c478bd9Sstevel@tonic-gate 		return (0);
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	for (items = 0, bytes = 0; items < nitems; items++) {
258*7c478bd9Sstevel@tonic-gate 		bytes = read(stream->_file, &strp[totbytes], size);
259*7c478bd9Sstevel@tonic-gate 		if (bytes < 0) {
260*7c478bd9Sstevel@tonic-gate 			stream->_flag |= F_ERROR;
261*7c478bd9Sstevel@tonic-gate 			return (0);
262*7c478bd9Sstevel@tonic-gate 		} else if (bytes == 0) {
263*7c478bd9Sstevel@tonic-gate 			/* EOF */
264*7c478bd9Sstevel@tonic-gate 			return ((totbytes == 0) ? 0 : totbytes / size);
265*7c478bd9Sstevel@tonic-gate 		} else if (bytes == size) {
266*7c478bd9Sstevel@tonic-gate 			stream->_offset += bytes;
267*7c478bd9Sstevel@tonic-gate 			totbytes += bytes;
268*7c478bd9Sstevel@tonic-gate 		} else {
269*7c478bd9Sstevel@tonic-gate 			(void) lseek(stream->_file, stream->_offset, SEEK_SET);
270*7c478bd9Sstevel@tonic-gate 			return (totbytes / size);
271*7c478bd9Sstevel@tonic-gate 		}
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	return (totbytes / size);
275*7c478bd9Sstevel@tonic-gate }
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate /*
278*7c478bd9Sstevel@tonic-gate  * We don't grow files.
279*7c478bd9Sstevel@tonic-gate  */
280*7c478bd9Sstevel@tonic-gate int
281*7c478bd9Sstevel@tonic-gate fseek(FILE *stream, long offset, int whence)
282*7c478bd9Sstevel@tonic-gate {
283*7c478bd9Sstevel@tonic-gate 	off_t	new_offset, result;
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN | F_SEEKABLE))
286*7c478bd9Sstevel@tonic-gate 		return (-1);
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	switch (whence) {
289*7c478bd9Sstevel@tonic-gate 	case SEEK_SET:
290*7c478bd9Sstevel@tonic-gate 		new_offset = (off_t)offset;
291*7c478bd9Sstevel@tonic-gate 		break;
292*7c478bd9Sstevel@tonic-gate 	case SEEK_CUR:
293*7c478bd9Sstevel@tonic-gate 		new_offset = stream->_offset + (off_t)offset;
294*7c478bd9Sstevel@tonic-gate 		break;
295*7c478bd9Sstevel@tonic-gate 	case SEEK_END:
296*7c478bd9Sstevel@tonic-gate 		new_offset = (off_t)stream->_len + (off_t)offset;
297*7c478bd9Sstevel@tonic-gate 		break;
298*7c478bd9Sstevel@tonic-gate 	default:
299*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
300*7c478bd9Sstevel@tonic-gate 		return (-1);
301*7c478bd9Sstevel@tonic-gate 	}
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	if (new_offset > (off_t)stream->_len) {
304*7c478bd9Sstevel@tonic-gate 		errno = EFBIG;
305*7c478bd9Sstevel@tonic-gate 	} else if (new_offset < 0L) {
306*7c478bd9Sstevel@tonic-gate 		errno = EOVERFLOW;
307*7c478bd9Sstevel@tonic-gate 	} else {
308*7c478bd9Sstevel@tonic-gate 		errno = 0;
309*7c478bd9Sstevel@tonic-gate 	}
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 	result = lseek(stream->_file, new_offset, SEEK_SET);
312*7c478bd9Sstevel@tonic-gate 	if (result >= 0)
313*7c478bd9Sstevel@tonic-gate 		stream->_offset = result;
314*7c478bd9Sstevel@tonic-gate 	else
315*7c478bd9Sstevel@tonic-gate 		stream->_flag |= F_ERROR;
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	return (result);
318*7c478bd9Sstevel@tonic-gate }
319*7c478bd9Sstevel@tonic-gate 
320*7c478bd9Sstevel@tonic-gate long
321*7c478bd9Sstevel@tonic-gate ftell(FILE *stream)
322*7c478bd9Sstevel@tonic-gate {
323*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN | F_SEEKABLE))
324*7c478bd9Sstevel@tonic-gate 		return (0);
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 	return ((long)stream->_offset);
327*7c478bd9Sstevel@tonic-gate }
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate size_t
330*7c478bd9Sstevel@tonic-gate fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
331*7c478bd9Sstevel@tonic-gate {
332*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
333*7c478bd9Sstevel@tonic-gate 		return (0);
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	/*
336*7c478bd9Sstevel@tonic-gate 	 * Since fopen() doesn't return writable streams, the only valid
337*7c478bd9Sstevel@tonic-gate 	 * writable streams are stdout and stderr.
338*7c478bd9Sstevel@tonic-gate 	 */
339*7c478bd9Sstevel@tonic-gate 	if (stream != stdout && stream != stderr) {
340*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
341*7c478bd9Sstevel@tonic-gate 		return (0);
342*7c478bd9Sstevel@tonic-gate 	}
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 	prom_writestr(ptr, size * nitems);
345*7c478bd9Sstevel@tonic-gate 	return (nitems);
346*7c478bd9Sstevel@tonic-gate }
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
349*7c478bd9Sstevel@tonic-gate int
350*7c478bd9Sstevel@tonic-gate setvbuf(FILE *stream, char *buf, int type, size_t size)
351*7c478bd9Sstevel@tonic-gate {
352*7c478bd9Sstevel@tonic-gate 	if (!fcheck(stream, F_OPEN))
353*7c478bd9Sstevel@tonic-gate 		return (-1);
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 	/* Currently a nop, probably always will be. */
356*7c478bd9Sstevel@tonic-gate 	return (0);
357*7c478bd9Sstevel@tonic-gate }
358