xref: /titanic_53/usr/src/test/libc-tests/tests/stdio/memstream.c (revision f65a228f854974d51b13928c21fa0ae281aa80af)
1*f65a228fSRobert Mustacchi /*
2*f65a228fSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*f65a228fSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*f65a228fSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*f65a228fSRobert Mustacchi  * 1.0 of the CDDL.
6*f65a228fSRobert Mustacchi  *
7*f65a228fSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*f65a228fSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*f65a228fSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*f65a228fSRobert Mustacchi  */
11*f65a228fSRobert Mustacchi 
12*f65a228fSRobert Mustacchi /*
13*f65a228fSRobert Mustacchi  * Copyright 2020 Robert Mustacchi
14*f65a228fSRobert Mustacchi  */
15*f65a228fSRobert Mustacchi 
16*f65a228fSRobert Mustacchi /*
17*f65a228fSRobert Mustacchi  * Test memory based streams: opem_memstream(3C), open_wmemstream(3C), and
18*f65a228fSRobert Mustacchi  * fmemopen(3C).
19*f65a228fSRobert Mustacchi  */
20*f65a228fSRobert Mustacchi 
21*f65a228fSRobert Mustacchi #include <stdio.h>
22*f65a228fSRobert Mustacchi #include <stdlib.h>
23*f65a228fSRobert Mustacchi #include <sys/types.h>
24*f65a228fSRobert Mustacchi #include <sys/sysmacros.h>
25*f65a228fSRobert Mustacchi #include <strings.h>
26*f65a228fSRobert Mustacchi #include <err.h>
27*f65a228fSRobert Mustacchi #include <errno.h>
28*f65a228fSRobert Mustacchi #include <wchar.h>
29*f65a228fSRobert Mustacchi #include <umem.h>
30*f65a228fSRobert Mustacchi #include <locale.h>
31*f65a228fSRobert Mustacchi 
32*f65a228fSRobert Mustacchi typedef boolean_t (*memstream_test_f)(void);
33*f65a228fSRobert Mustacchi static char *fmemopen_str1 = "The Road goes ever on and on\n"
34*f65a228fSRobert Mustacchi 	"Down from the door where it began.\n";
35*f65a228fSRobert Mustacchi const wchar_t *wstream_str = L"いつか終わる夢";
36*f65a228fSRobert Mustacchi /*
37*f65a228fSRobert Mustacchi  * smatch doesn't support wide-character constants (wchar_t foo = L'xxx'), so
38*f65a228fSRobert Mustacchi  * instead use a string which it'll happily accept.
39*f65a228fSRobert Mustacchi  */
40*f65a228fSRobert Mustacchi const wchar_t *wstr_const = L"光";
41*f65a228fSRobert Mustacchi 
42*f65a228fSRobert Mustacchi const char *
_umem_debug_init(void)43*f65a228fSRobert Mustacchi _umem_debug_init(void)
44*f65a228fSRobert Mustacchi {
45*f65a228fSRobert Mustacchi 	return ("default,verbose");
46*f65a228fSRobert Mustacchi }
47*f65a228fSRobert Mustacchi 
48*f65a228fSRobert Mustacchi const char *
_umem_logging_init(void)49*f65a228fSRobert Mustacchi _umem_logging_init(void)
50*f65a228fSRobert Mustacchi {
51*f65a228fSRobert Mustacchi 	return ("fail,contents");
52*f65a228fSRobert Mustacchi }
53*f65a228fSRobert Mustacchi 
54*f65a228fSRobert Mustacchi static boolean_t
fmemopen_badopen(void * buf,size_t size,const char * mode,int err)55*f65a228fSRobert Mustacchi fmemopen_badopen(void *buf, size_t size, const char *mode, int err)
56*f65a228fSRobert Mustacchi {
57*f65a228fSRobert Mustacchi 	FILE *f = fmemopen(buf, size, mode);
58*f65a228fSRobert Mustacchi 
59*f65a228fSRobert Mustacchi 	if (f != NULL) {
60*f65a228fSRobert Mustacchi 		warnx("fmemopen() succeeded erroneously");
61*f65a228fSRobert Mustacchi 		(void) fclose(f);
62*f65a228fSRobert Mustacchi 		return (B_FALSE);
63*f65a228fSRobert Mustacchi 	}
64*f65a228fSRobert Mustacchi 
65*f65a228fSRobert Mustacchi 	if (errno != err) {
66*f65a228fSRobert Mustacchi 		warnx("fmemopen() open failed with wrong errno, "
67*f65a228fSRobert Mustacchi 		    "found %d (%s), expected %d (%s)", errno, strerror(errno),
68*f65a228fSRobert Mustacchi 		    err, strerror(err));
69*f65a228fSRobert Mustacchi 		return (B_FALSE);
70*f65a228fSRobert Mustacchi 	}
71*f65a228fSRobert Mustacchi 
72*f65a228fSRobert Mustacchi 	return (B_TRUE);
73*f65a228fSRobert Mustacchi }
74*f65a228fSRobert Mustacchi 
75*f65a228fSRobert Mustacchi static boolean_t
fmemopen_badmode(void)76*f65a228fSRobert Mustacchi fmemopen_badmode(void)
77*f65a228fSRobert Mustacchi {
78*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(fmemopen_str1, strlen(fmemopen_str1), "foobar",
79*f65a228fSRobert Mustacchi 	    EINVAL));
80*f65a228fSRobert Mustacchi }
81*f65a228fSRobert Mustacchi 
82*f65a228fSRobert Mustacchi static boolean_t
fmemopen_zerobuf1(void)83*f65a228fSRobert Mustacchi fmemopen_zerobuf1(void)
84*f65a228fSRobert Mustacchi {
85*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(fmemopen_str1, 0, "w", EINVAL));
86*f65a228fSRobert Mustacchi }
87*f65a228fSRobert Mustacchi 
88*f65a228fSRobert Mustacchi static boolean_t
fmemopen_zerobuf2(void)89*f65a228fSRobert Mustacchi fmemopen_zerobuf2(void)
90*f65a228fSRobert Mustacchi {
91*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, 0, "w+", EINVAL));
92*f65a228fSRobert Mustacchi }
93*f65a228fSRobert Mustacchi 
94*f65a228fSRobert Mustacchi static boolean_t
fmemopen_nullbuf1(void)95*f65a228fSRobert Mustacchi fmemopen_nullbuf1(void)
96*f65a228fSRobert Mustacchi {
97*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, 10, "r", EINVAL));
98*f65a228fSRobert Mustacchi }
99*f65a228fSRobert Mustacchi 
100*f65a228fSRobert Mustacchi static boolean_t
fmemopen_nullbuf2(void)101*f65a228fSRobert Mustacchi fmemopen_nullbuf2(void)
102*f65a228fSRobert Mustacchi {
103*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, 10, "w", EINVAL));
104*f65a228fSRobert Mustacchi }
105*f65a228fSRobert Mustacchi 
106*f65a228fSRobert Mustacchi static boolean_t
fmemopen_nullbuf3(void)107*f65a228fSRobert Mustacchi fmemopen_nullbuf3(void)
108*f65a228fSRobert Mustacchi {
109*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, 10, "a", EINVAL));
110*f65a228fSRobert Mustacchi }
111*f65a228fSRobert Mustacchi 
112*f65a228fSRobert Mustacchi static boolean_t
fmemopen_nullbuf4(void)113*f65a228fSRobert Mustacchi fmemopen_nullbuf4(void)
114*f65a228fSRobert Mustacchi {
115*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, 10, "ax", EINVAL));
116*f65a228fSRobert Mustacchi }
117*f65a228fSRobert Mustacchi 
118*f65a228fSRobert Mustacchi static boolean_t
fmemopen_sizemax(void)119*f65a228fSRobert Mustacchi fmemopen_sizemax(void)
120*f65a228fSRobert Mustacchi {
121*f65a228fSRobert Mustacchi 	return (fmemopen_badopen(NULL, SIZE_MAX, "w+", ENOMEM));
122*f65a228fSRobert Mustacchi }
123*f65a228fSRobert Mustacchi 
124*f65a228fSRobert Mustacchi static boolean_t
fmemopen_cantalloc(void)125*f65a228fSRobert Mustacchi fmemopen_cantalloc(void)
126*f65a228fSRobert Mustacchi {
127*f65a228fSRobert Mustacchi 	boolean_t ret;
128*f65a228fSRobert Mustacchi 
129*f65a228fSRobert Mustacchi 	umem_setmtbf(1);
130*f65a228fSRobert Mustacchi 	ret = fmemopen_badopen(NULL, 10, "w+", ENOMEM);
131*f65a228fSRobert Mustacchi 	umem_setmtbf(0);
132*f65a228fSRobert Mustacchi 	return (ret);
133*f65a228fSRobert Mustacchi }
134*f65a228fSRobert Mustacchi 
135*f65a228fSRobert Mustacchi static boolean_t
open_memstream_badopen(char ** bufp,size_t * sizep,int err)136*f65a228fSRobert Mustacchi open_memstream_badopen(char **bufp, size_t *sizep, int err)
137*f65a228fSRobert Mustacchi {
138*f65a228fSRobert Mustacchi 	FILE *f = open_memstream(bufp, sizep);
139*f65a228fSRobert Mustacchi 
140*f65a228fSRobert Mustacchi 	if (f != NULL) {
141*f65a228fSRobert Mustacchi 		warnx("open_memstream() succeeded erroneously");
142*f65a228fSRobert Mustacchi 		(void) fclose(f);
143*f65a228fSRobert Mustacchi 		return (B_FALSE);
144*f65a228fSRobert Mustacchi 	}
145*f65a228fSRobert Mustacchi 
146*f65a228fSRobert Mustacchi 	if (errno != err) {
147*f65a228fSRobert Mustacchi 		warnx("open_memstream() open failed with wrong errno, "
148*f65a228fSRobert Mustacchi 		    "found %d (%s), expected %d (%s)", errno, strerror(errno),
149*f65a228fSRobert Mustacchi 		    err, strerror(err));
150*f65a228fSRobert Mustacchi 		return (B_FALSE);
151*f65a228fSRobert Mustacchi 	}
152*f65a228fSRobert Mustacchi 
153*f65a228fSRobert Mustacchi 	return (B_TRUE);
154*f65a228fSRobert Mustacchi }
155*f65a228fSRobert Mustacchi 
156*f65a228fSRobert Mustacchi static boolean_t
open_memstream_badbuf(void)157*f65a228fSRobert Mustacchi open_memstream_badbuf(void)
158*f65a228fSRobert Mustacchi {
159*f65a228fSRobert Mustacchi 	size_t s, check;
160*f65a228fSRobert Mustacchi 	boolean_t ret;
161*f65a228fSRobert Mustacchi 
162*f65a228fSRobert Mustacchi 	arc4random_buf(&s, sizeof (s));
163*f65a228fSRobert Mustacchi 	check = s;
164*f65a228fSRobert Mustacchi 	ret = open_memstream_badopen(NULL, &s, EINVAL);
165*f65a228fSRobert Mustacchi 	if (check != s) {
166*f65a228fSRobert Mustacchi 		warnx("open_memstream() open erroneously wrote to size "
167*f65a228fSRobert Mustacchi 		    "pointer");
168*f65a228fSRobert Mustacchi 		return (B_FALSE);
169*f65a228fSRobert Mustacchi 	}
170*f65a228fSRobert Mustacchi 	return (ret);
171*f65a228fSRobert Mustacchi }
172*f65a228fSRobert Mustacchi 
173*f65a228fSRobert Mustacchi static boolean_t
open_memstream_badsize(void)174*f65a228fSRobert Mustacchi open_memstream_badsize(void)
175*f65a228fSRobert Mustacchi {
176*f65a228fSRobert Mustacchi 	char *c;
177*f65a228fSRobert Mustacchi 	return (open_memstream_badopen(&c, NULL, EINVAL));
178*f65a228fSRobert Mustacchi }
179*f65a228fSRobert Mustacchi 
180*f65a228fSRobert Mustacchi static boolean_t
open_memstream_allnull(void)181*f65a228fSRobert Mustacchi open_memstream_allnull(void)
182*f65a228fSRobert Mustacchi {
183*f65a228fSRobert Mustacchi 	return (open_memstream_badopen(NULL, NULL, EINVAL));
184*f65a228fSRobert Mustacchi }
185*f65a228fSRobert Mustacchi 
186*f65a228fSRobert Mustacchi static boolean_t
open_memstream_cantalloc(void)187*f65a228fSRobert Mustacchi open_memstream_cantalloc(void)
188*f65a228fSRobert Mustacchi {
189*f65a228fSRobert Mustacchi 	boolean_t ret;
190*f65a228fSRobert Mustacchi 	char *c;
191*f65a228fSRobert Mustacchi 	size_t len;
192*f65a228fSRobert Mustacchi 
193*f65a228fSRobert Mustacchi 	umem_setmtbf(1);
194*f65a228fSRobert Mustacchi 	ret = open_memstream_badopen(&c, &len, EAGAIN);
195*f65a228fSRobert Mustacchi 	umem_setmtbf(0);
196*f65a228fSRobert Mustacchi 	return (ret);
197*f65a228fSRobert Mustacchi }
198*f65a228fSRobert Mustacchi 
199*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_badopen(wchar_t ** bufp,size_t * sizep,int err)200*f65a228fSRobert Mustacchi open_wmemstream_badopen(wchar_t **bufp, size_t *sizep, int err)
201*f65a228fSRobert Mustacchi {
202*f65a228fSRobert Mustacchi 	FILE *f = open_wmemstream(bufp, sizep);
203*f65a228fSRobert Mustacchi 
204*f65a228fSRobert Mustacchi 	if (f != NULL) {
205*f65a228fSRobert Mustacchi 		warnx("open_wmemstream() succeeded erroneously");
206*f65a228fSRobert Mustacchi 		(void) fclose(f);
207*f65a228fSRobert Mustacchi 		return (B_FALSE);
208*f65a228fSRobert Mustacchi 	}
209*f65a228fSRobert Mustacchi 
210*f65a228fSRobert Mustacchi 	if (errno != err) {
211*f65a228fSRobert Mustacchi 		warnx("open_wmemstream() open failed with wrong errno, "
212*f65a228fSRobert Mustacchi 		    "found %d (%s), expected %d (%s)", errno, strerror(errno),
213*f65a228fSRobert Mustacchi 		    err, strerror(err));
214*f65a228fSRobert Mustacchi 		return (B_FALSE);
215*f65a228fSRobert Mustacchi 	}
216*f65a228fSRobert Mustacchi 
217*f65a228fSRobert Mustacchi 	return (B_TRUE);
218*f65a228fSRobert Mustacchi }
219*f65a228fSRobert Mustacchi 
220*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_badbuf(void)221*f65a228fSRobert Mustacchi open_wmemstream_badbuf(void)
222*f65a228fSRobert Mustacchi {
223*f65a228fSRobert Mustacchi 	size_t s, check;
224*f65a228fSRobert Mustacchi 	boolean_t ret;
225*f65a228fSRobert Mustacchi 
226*f65a228fSRobert Mustacchi 	arc4random_buf(&s, sizeof (s));
227*f65a228fSRobert Mustacchi 	check = s;
228*f65a228fSRobert Mustacchi 	ret = open_wmemstream_badopen(NULL, &s, EINVAL);
229*f65a228fSRobert Mustacchi 	if (check != s) {
230*f65a228fSRobert Mustacchi 		warnx("open_wmemstream() open erroneously wrote to size "
231*f65a228fSRobert Mustacchi 		    "pointer");
232*f65a228fSRobert Mustacchi 		return (B_FALSE);
233*f65a228fSRobert Mustacchi 	}
234*f65a228fSRobert Mustacchi 	return (ret);
235*f65a228fSRobert Mustacchi }
236*f65a228fSRobert Mustacchi 
237*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_badsize(void)238*f65a228fSRobert Mustacchi open_wmemstream_badsize(void)
239*f65a228fSRobert Mustacchi {
240*f65a228fSRobert Mustacchi 	wchar_t *c;
241*f65a228fSRobert Mustacchi 	return (open_wmemstream_badopen(&c, NULL, EINVAL));
242*f65a228fSRobert Mustacchi }
243*f65a228fSRobert Mustacchi 
244*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_allnull(void)245*f65a228fSRobert Mustacchi open_wmemstream_allnull(void)
246*f65a228fSRobert Mustacchi {
247*f65a228fSRobert Mustacchi 	return (open_wmemstream_badopen(NULL, NULL, EINVAL));
248*f65a228fSRobert Mustacchi }
249*f65a228fSRobert Mustacchi 
250*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_cantalloc(void)251*f65a228fSRobert Mustacchi open_wmemstream_cantalloc(void)
252*f65a228fSRobert Mustacchi {
253*f65a228fSRobert Mustacchi 	boolean_t ret;
254*f65a228fSRobert Mustacchi 	wchar_t *c;
255*f65a228fSRobert Mustacchi 	size_t len;
256*f65a228fSRobert Mustacchi 
257*f65a228fSRobert Mustacchi 	umem_setmtbf(1);
258*f65a228fSRobert Mustacchi 	ret = open_wmemstream_badopen(&c, &len, EAGAIN);
259*f65a228fSRobert Mustacchi 	umem_setmtbf(0);
260*f65a228fSRobert Mustacchi 	return (ret);
261*f65a228fSRobert Mustacchi }
262*f65a228fSRobert Mustacchi 
263*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_putc(FILE * f,size_t len,boolean_t buffer)264*f65a228fSRobert Mustacchi fmemopen_fill_putc(FILE *f, size_t len, boolean_t buffer)
265*f65a228fSRobert Mustacchi {
266*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
267*f65a228fSRobert Mustacchi 	size_t i;
268*f65a228fSRobert Mustacchi 
269*f65a228fSRobert Mustacchi 	for (i = 0; i < BUFSIZ * 2; i++) {
270*f65a228fSRobert Mustacchi 		if (fputc('a', f) != 'a') {
271*f65a228fSRobert Mustacchi 			break;
272*f65a228fSRobert Mustacchi 		}
273*f65a228fSRobert Mustacchi 	}
274*f65a228fSRobert Mustacchi 
275*f65a228fSRobert Mustacchi 	if (buffer) {
276*f65a228fSRobert Mustacchi 		if (i < len) {
277*f65a228fSRobert Mustacchi 			warnx("write mismatch, had %zu bytes, wrote %zu",
278*f65a228fSRobert Mustacchi 			    len, i);
279*f65a228fSRobert Mustacchi 			ret = B_FALSE;
280*f65a228fSRobert Mustacchi 		}
281*f65a228fSRobert Mustacchi 
282*f65a228fSRobert Mustacchi 		if (fflush(f) == 0) {
283*f65a228fSRobert Mustacchi 			warnx("somehow flushed overly full stream, expected "
284*f65a228fSRobert Mustacchi 			    "failure");
285*f65a228fSRobert Mustacchi 			ret = B_FALSE;
286*f65a228fSRobert Mustacchi 		}
287*f65a228fSRobert Mustacchi 	} else if (i != len) {
288*f65a228fSRobert Mustacchi 		warnx("write mismatch, had %zu bytes, wrote %zu", len, i);
289*f65a228fSRobert Mustacchi 		ret = B_FALSE;
290*f65a228fSRobert Mustacchi 	}
291*f65a228fSRobert Mustacchi 
292*f65a228fSRobert Mustacchi 	if (feof(f) != 0) {
293*f65a228fSRobert Mustacchi 		warn("EOF mistakenly set on write");
294*f65a228fSRobert Mustacchi 		ret = B_FALSE;
295*f65a228fSRobert Mustacchi 	}
296*f65a228fSRobert Mustacchi 
297*f65a228fSRobert Mustacchi 	if (ferror(f) == 0) {
298*f65a228fSRobert Mustacchi 		warn("feof not set on write past the end");
299*f65a228fSRobert Mustacchi 		ret = B_FALSE;
300*f65a228fSRobert Mustacchi 	}
301*f65a228fSRobert Mustacchi 
302*f65a228fSRobert Mustacchi 	if (fclose(f) != 0) {
303*f65a228fSRobert Mustacchi 		warn("failed to close memory stream");
304*f65a228fSRobert Mustacchi 		return (B_FALSE);
305*f65a228fSRobert Mustacchi 	}
306*f65a228fSRobert Mustacchi 
307*f65a228fSRobert Mustacchi 	return (ret);
308*f65a228fSRobert Mustacchi }
309*f65a228fSRobert Mustacchi 
310*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_fwrite(FILE * f,size_t len,boolean_t buffer)311*f65a228fSRobert Mustacchi fmemopen_fill_fwrite(FILE *f, size_t len, boolean_t buffer)
312*f65a228fSRobert Mustacchi {
313*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
314*f65a228fSRobert Mustacchi 	size_t i;
315*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
316*f65a228fSRobert Mustacchi 
317*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
318*f65a228fSRobert Mustacchi 	i = fwrite(buf, sizeof (buf), 1, f);
319*f65a228fSRobert Mustacchi 
320*f65a228fSRobert Mustacchi 	if (buffer) {
321*f65a228fSRobert Mustacchi 		if (i != 1) {
322*f65a228fSRobert Mustacchi 			warnx("write mismatch, expected 1 entry, found %zu", i);
323*f65a228fSRobert Mustacchi 			ret = B_FALSE;
324*f65a228fSRobert Mustacchi 		}
325*f65a228fSRobert Mustacchi 
326*f65a228fSRobert Mustacchi 		if (fflush(f) == 0) {
327*f65a228fSRobert Mustacchi 			warnx("somehow flushed overly full stream, expected "
328*f65a228fSRobert Mustacchi 			    "failure");
329*f65a228fSRobert Mustacchi 			ret = B_FALSE;
330*f65a228fSRobert Mustacchi 		}
331*f65a228fSRobert Mustacchi 	} else if (i != 0 && i != len) {
332*f65a228fSRobert Mustacchi 		warnx("write mismatch, had %zu bytes, wrote %zu", len, i);
333*f65a228fSRobert Mustacchi 		ret = B_FALSE;
334*f65a228fSRobert Mustacchi 	}
335*f65a228fSRobert Mustacchi 
336*f65a228fSRobert Mustacchi 	if (feof(f) != 0) {
337*f65a228fSRobert Mustacchi 		warn("EOF mistakenly set on write");
338*f65a228fSRobert Mustacchi 		ret = B_FALSE;
339*f65a228fSRobert Mustacchi 	}
340*f65a228fSRobert Mustacchi 
341*f65a228fSRobert Mustacchi 	if (ferror(f) == 0) {
342*f65a228fSRobert Mustacchi 		warn("feof not set on write past the end");
343*f65a228fSRobert Mustacchi 		ret = B_FALSE;
344*f65a228fSRobert Mustacchi 	}
345*f65a228fSRobert Mustacchi 
346*f65a228fSRobert Mustacchi 	if (fclose(f) != 0) {
347*f65a228fSRobert Mustacchi 		warn("failed to close memory stream");
348*f65a228fSRobert Mustacchi 		return (B_FALSE);
349*f65a228fSRobert Mustacchi 	}
350*f65a228fSRobert Mustacchi 
351*f65a228fSRobert Mustacchi 	return (ret);
352*f65a228fSRobert Mustacchi }
353*f65a228fSRobert Mustacchi 
354*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_alt_fwrite(FILE * f,size_t len,boolean_t buffer)355*f65a228fSRobert Mustacchi fmemopen_fill_alt_fwrite(FILE *f, size_t len, boolean_t buffer)
356*f65a228fSRobert Mustacchi {
357*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
358*f65a228fSRobert Mustacchi 	size_t i;
359*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
360*f65a228fSRobert Mustacchi 
361*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
362*f65a228fSRobert Mustacchi 	i = fwrite(buf, 1, sizeof (buf), f);
363*f65a228fSRobert Mustacchi 
364*f65a228fSRobert Mustacchi 	if (buffer) {
365*f65a228fSRobert Mustacchi 		if (i < len) {
366*f65a228fSRobert Mustacchi 			warnx("write mismatch, had %zu bytes, wrote %zu",
367*f65a228fSRobert Mustacchi 			    len, i);
368*f65a228fSRobert Mustacchi 			ret = B_FALSE;
369*f65a228fSRobert Mustacchi 		}
370*f65a228fSRobert Mustacchi 
371*f65a228fSRobert Mustacchi 		if (fflush(f) == 0) {
372*f65a228fSRobert Mustacchi 			warnx("somehow flushed overly full stream, expected "
373*f65a228fSRobert Mustacchi 			    "failure");
374*f65a228fSRobert Mustacchi 			ret = B_FALSE;
375*f65a228fSRobert Mustacchi 		}
376*f65a228fSRobert Mustacchi 	} else if (i != len) {
377*f65a228fSRobert Mustacchi 		warnx("write mismatch, had %zu bytes, wrote %zu", len, i);
378*f65a228fSRobert Mustacchi 		ret = B_FALSE;
379*f65a228fSRobert Mustacchi 	}
380*f65a228fSRobert Mustacchi 
381*f65a228fSRobert Mustacchi 	if (feof(f) != 0) {
382*f65a228fSRobert Mustacchi 		warn("EOF mistakenly set on write");
383*f65a228fSRobert Mustacchi 		ret = B_FALSE;
384*f65a228fSRobert Mustacchi 	}
385*f65a228fSRobert Mustacchi 
386*f65a228fSRobert Mustacchi 	if (ferror(f) == 0) {
387*f65a228fSRobert Mustacchi 		warn("feof not set on write past the end");
388*f65a228fSRobert Mustacchi 		ret = B_FALSE;
389*f65a228fSRobert Mustacchi 	}
390*f65a228fSRobert Mustacchi 
391*f65a228fSRobert Mustacchi 	if (fclose(f) != 0) {
392*f65a228fSRobert Mustacchi 		warn("failed to close memory stream");
393*f65a228fSRobert Mustacchi 		return (B_FALSE);
394*f65a228fSRobert Mustacchi 	}
395*f65a228fSRobert Mustacchi 
396*f65a228fSRobert Mustacchi 	return (ret);
397*f65a228fSRobert Mustacchi }
398*f65a228fSRobert Mustacchi 
399*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_fputs(FILE * f,size_t len,boolean_t buffer)400*f65a228fSRobert Mustacchi fmemopen_fill_fputs(FILE *f, size_t len, boolean_t buffer)
401*f65a228fSRobert Mustacchi {
402*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
403*f65a228fSRobert Mustacchi 	size_t i;
404*f65a228fSRobert Mustacchi 	char buf[17];
405*f65a228fSRobert Mustacchi 
406*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
407*f65a228fSRobert Mustacchi 	buf[16] = '\0';
408*f65a228fSRobert Mustacchi 	for (i = 0; i < BUFSIZ * 2; i += 16) {
409*f65a228fSRobert Mustacchi 		if (fputs(buf, f) != 16) {
410*f65a228fSRobert Mustacchi 			break;
411*f65a228fSRobert Mustacchi 		}
412*f65a228fSRobert Mustacchi 	}
413*f65a228fSRobert Mustacchi 
414*f65a228fSRobert Mustacchi 	/*
415*f65a228fSRobert Mustacchi 	 * We don't check flushing in the puts case because fputs seems to clear
416*f65a228fSRobert Mustacchi 	 * the buffer as a side effect.
417*f65a228fSRobert Mustacchi 	 */
418*f65a228fSRobert Mustacchi 	if (buffer) {
419*f65a228fSRobert Mustacchi 		if (i < len) {
420*f65a228fSRobert Mustacchi 			warnx("write mismatch, had %zu bytes, wrote %zu",
421*f65a228fSRobert Mustacchi 			    len, i);
422*f65a228fSRobert Mustacchi 			ret = B_FALSE;
423*f65a228fSRobert Mustacchi 		}
424*f65a228fSRobert Mustacchi 	} else if (i != len) {
425*f65a228fSRobert Mustacchi 		warnx("write mismatch, had %zu bytes, wrote %zu", len, i);
426*f65a228fSRobert Mustacchi 		ret = B_FALSE;
427*f65a228fSRobert Mustacchi 	}
428*f65a228fSRobert Mustacchi 
429*f65a228fSRobert Mustacchi 	if (feof(f) != 0) {
430*f65a228fSRobert Mustacchi 		warn("EOF mistakenly set on write");
431*f65a228fSRobert Mustacchi 		ret = B_FALSE;
432*f65a228fSRobert Mustacchi 	}
433*f65a228fSRobert Mustacchi 
434*f65a228fSRobert Mustacchi 	if (ferror(f) == 0) {
435*f65a228fSRobert Mustacchi 		warn("feof not set on write past the end");
436*f65a228fSRobert Mustacchi 		ret = B_FALSE;
437*f65a228fSRobert Mustacchi 	}
438*f65a228fSRobert Mustacchi 
439*f65a228fSRobert Mustacchi 	if (fclose(f) != 0) {
440*f65a228fSRobert Mustacchi 		warn("failed to close memory stream");
441*f65a228fSRobert Mustacchi 		return (B_FALSE);
442*f65a228fSRobert Mustacchi 	}
443*f65a228fSRobert Mustacchi 
444*f65a228fSRobert Mustacchi 	return (ret);
445*f65a228fSRobert Mustacchi }
446*f65a228fSRobert Mustacchi 
447*f65a228fSRobert Mustacchi 
448*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_default(void)449*f65a228fSRobert Mustacchi fmemopen_fill_default(void)
450*f65a228fSRobert Mustacchi {
451*f65a228fSRobert Mustacchi 	FILE *f;
452*f65a228fSRobert Mustacchi 
453*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
454*f65a228fSRobert Mustacchi 	if (f == NULL) {
455*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
456*f65a228fSRobert Mustacchi 		return (B_FALSE);
457*f65a228fSRobert Mustacchi 	}
458*f65a228fSRobert Mustacchi 
459*f65a228fSRobert Mustacchi 	return (fmemopen_fill_putc(f, 128, B_TRUE));
460*f65a228fSRobert Mustacchi }
461*f65a228fSRobert Mustacchi 
462*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_lbuf(void)463*f65a228fSRobert Mustacchi fmemopen_fill_lbuf(void)
464*f65a228fSRobert Mustacchi {
465*f65a228fSRobert Mustacchi 	FILE *f;
466*f65a228fSRobert Mustacchi 
467*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
468*f65a228fSRobert Mustacchi 	if (f == NULL) {
469*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
470*f65a228fSRobert Mustacchi 		return (B_FALSE);
471*f65a228fSRobert Mustacchi 	}
472*f65a228fSRobert Mustacchi 
473*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IOLBF, BUFSIZ) != 0) {
474*f65a228fSRobert Mustacchi 		warn("failed to set buffer to line-buffered mode");
475*f65a228fSRobert Mustacchi 	}
476*f65a228fSRobert Mustacchi 
477*f65a228fSRobert Mustacchi 	return (fmemopen_fill_putc(f, 128, B_TRUE));
478*f65a228fSRobert Mustacchi }
479*f65a228fSRobert Mustacchi 
480*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fill_nobuf(void)481*f65a228fSRobert Mustacchi fmemopen_fill_nobuf(void)
482*f65a228fSRobert Mustacchi {
483*f65a228fSRobert Mustacchi 	FILE *f;
484*f65a228fSRobert Mustacchi 
485*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
486*f65a228fSRobert Mustacchi 	if (f == NULL) {
487*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
488*f65a228fSRobert Mustacchi 		return (B_FALSE);
489*f65a228fSRobert Mustacchi 	}
490*f65a228fSRobert Mustacchi 
491*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
492*f65a228fSRobert Mustacchi 		warn("failed to set buffer to non-buffered mode");
493*f65a228fSRobert Mustacchi 	}
494*f65a228fSRobert Mustacchi 
495*f65a228fSRobert Mustacchi 	return (fmemopen_fill_putc(f, 128, B_FALSE));
496*f65a228fSRobert Mustacchi }
497*f65a228fSRobert Mustacchi 
498*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fwrite_default(void)499*f65a228fSRobert Mustacchi fmemopen_fwrite_default(void)
500*f65a228fSRobert Mustacchi {
501*f65a228fSRobert Mustacchi 	FILE *f;
502*f65a228fSRobert Mustacchi 
503*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
504*f65a228fSRobert Mustacchi 	if (f == NULL) {
505*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
506*f65a228fSRobert Mustacchi 		return (B_FALSE);
507*f65a228fSRobert Mustacchi 	}
508*f65a228fSRobert Mustacchi 
509*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fwrite(f, 128, B_TRUE));
510*f65a228fSRobert Mustacchi }
511*f65a228fSRobert Mustacchi 
512*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fwrite_lbuf(void)513*f65a228fSRobert Mustacchi fmemopen_fwrite_lbuf(void)
514*f65a228fSRobert Mustacchi {
515*f65a228fSRobert Mustacchi 	FILE *f;
516*f65a228fSRobert Mustacchi 
517*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
518*f65a228fSRobert Mustacchi 	if (f == NULL) {
519*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
520*f65a228fSRobert Mustacchi 		return (B_FALSE);
521*f65a228fSRobert Mustacchi 	}
522*f65a228fSRobert Mustacchi 
523*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IOLBF, BUFSIZ) != 0) {
524*f65a228fSRobert Mustacchi 		warn("failed to set buffer to line-buffered mode");
525*f65a228fSRobert Mustacchi 	}
526*f65a228fSRobert Mustacchi 
527*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fwrite(f, 128, B_TRUE));
528*f65a228fSRobert Mustacchi }
529*f65a228fSRobert Mustacchi 
530*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fwrite_nobuf(void)531*f65a228fSRobert Mustacchi fmemopen_fwrite_nobuf(void)
532*f65a228fSRobert Mustacchi {
533*f65a228fSRobert Mustacchi 	FILE *f;
534*f65a228fSRobert Mustacchi 
535*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
536*f65a228fSRobert Mustacchi 	if (f == NULL) {
537*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
538*f65a228fSRobert Mustacchi 		return (B_FALSE);
539*f65a228fSRobert Mustacchi 	}
540*f65a228fSRobert Mustacchi 
541*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
542*f65a228fSRobert Mustacchi 		warn("failed to set buffer to non-buffered mode");
543*f65a228fSRobert Mustacchi 	}
544*f65a228fSRobert Mustacchi 
545*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fwrite(f, 128, B_FALSE));
546*f65a228fSRobert Mustacchi }
547*f65a228fSRobert Mustacchi 
548*f65a228fSRobert Mustacchi static boolean_t
fmemopen_alt_fwrite_default(void)549*f65a228fSRobert Mustacchi fmemopen_alt_fwrite_default(void)
550*f65a228fSRobert Mustacchi {
551*f65a228fSRobert Mustacchi 	FILE *f;
552*f65a228fSRobert Mustacchi 
553*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
554*f65a228fSRobert Mustacchi 	if (f == NULL) {
555*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
556*f65a228fSRobert Mustacchi 		return (B_FALSE);
557*f65a228fSRobert Mustacchi 	}
558*f65a228fSRobert Mustacchi 
559*f65a228fSRobert Mustacchi 	return (fmemopen_fill_alt_fwrite(f, 128, B_TRUE));
560*f65a228fSRobert Mustacchi }
561*f65a228fSRobert Mustacchi 
562*f65a228fSRobert Mustacchi static boolean_t
fmemopen_alt_fwrite_lbuf(void)563*f65a228fSRobert Mustacchi fmemopen_alt_fwrite_lbuf(void)
564*f65a228fSRobert Mustacchi {
565*f65a228fSRobert Mustacchi 	FILE *f;
566*f65a228fSRobert Mustacchi 
567*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
568*f65a228fSRobert Mustacchi 	if (f == NULL) {
569*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
570*f65a228fSRobert Mustacchi 		return (B_FALSE);
571*f65a228fSRobert Mustacchi 	}
572*f65a228fSRobert Mustacchi 
573*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IOLBF, BUFSIZ) != 0) {
574*f65a228fSRobert Mustacchi 		warn("failed to set buffer to line-buffered mode");
575*f65a228fSRobert Mustacchi 	}
576*f65a228fSRobert Mustacchi 
577*f65a228fSRobert Mustacchi 	return (fmemopen_fill_alt_fwrite(f, 128, B_TRUE));
578*f65a228fSRobert Mustacchi }
579*f65a228fSRobert Mustacchi 
580*f65a228fSRobert Mustacchi static boolean_t
fmemopen_alt_fwrite_nobuf(void)581*f65a228fSRobert Mustacchi fmemopen_alt_fwrite_nobuf(void)
582*f65a228fSRobert Mustacchi {
583*f65a228fSRobert Mustacchi 	FILE *f;
584*f65a228fSRobert Mustacchi 
585*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
586*f65a228fSRobert Mustacchi 	if (f == NULL) {
587*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
588*f65a228fSRobert Mustacchi 		return (B_FALSE);
589*f65a228fSRobert Mustacchi 	}
590*f65a228fSRobert Mustacchi 
591*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
592*f65a228fSRobert Mustacchi 		warn("failed to set buffer to non-buffered mode");
593*f65a228fSRobert Mustacchi 	}
594*f65a228fSRobert Mustacchi 
595*f65a228fSRobert Mustacchi 	return (fmemopen_fill_alt_fwrite(f, 128, B_FALSE));
596*f65a228fSRobert Mustacchi }
597*f65a228fSRobert Mustacchi 
598*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fputs_default(void)599*f65a228fSRobert Mustacchi fmemopen_fputs_default(void)
600*f65a228fSRobert Mustacchi {
601*f65a228fSRobert Mustacchi 	FILE *f;
602*f65a228fSRobert Mustacchi 
603*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
604*f65a228fSRobert Mustacchi 	if (f == NULL) {
605*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
606*f65a228fSRobert Mustacchi 		return (B_FALSE);
607*f65a228fSRobert Mustacchi 	}
608*f65a228fSRobert Mustacchi 
609*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fputs(f, 128, B_TRUE));
610*f65a228fSRobert Mustacchi }
611*f65a228fSRobert Mustacchi 
612*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fputs_lbuf(void)613*f65a228fSRobert Mustacchi fmemopen_fputs_lbuf(void)
614*f65a228fSRobert Mustacchi {
615*f65a228fSRobert Mustacchi 	FILE *f;
616*f65a228fSRobert Mustacchi 
617*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
618*f65a228fSRobert Mustacchi 	if (f == NULL) {
619*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
620*f65a228fSRobert Mustacchi 		return (B_FALSE);
621*f65a228fSRobert Mustacchi 	}
622*f65a228fSRobert Mustacchi 
623*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IOLBF, BUFSIZ) != 0) {
624*f65a228fSRobert Mustacchi 		warn("failed to set buffer to line-buffered mode");
625*f65a228fSRobert Mustacchi 	}
626*f65a228fSRobert Mustacchi 
627*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fputs(f, 128, B_TRUE));
628*f65a228fSRobert Mustacchi }
629*f65a228fSRobert Mustacchi 
630*f65a228fSRobert Mustacchi static boolean_t
fmemopen_fputs_nobuf(void)631*f65a228fSRobert Mustacchi fmemopen_fputs_nobuf(void)
632*f65a228fSRobert Mustacchi {
633*f65a228fSRobert Mustacchi 	FILE *f;
634*f65a228fSRobert Mustacchi 
635*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, 128, "w+");
636*f65a228fSRobert Mustacchi 	if (f == NULL) {
637*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
638*f65a228fSRobert Mustacchi 		return (B_FALSE);
639*f65a228fSRobert Mustacchi 	}
640*f65a228fSRobert Mustacchi 
641*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
642*f65a228fSRobert Mustacchi 		warn("failed to set buffer to non-buffered mode");
643*f65a228fSRobert Mustacchi 	}
644*f65a228fSRobert Mustacchi 
645*f65a228fSRobert Mustacchi 	return (fmemopen_fill_fputs(f, 128, B_FALSE));
646*f65a228fSRobert Mustacchi }
647*f65a228fSRobert Mustacchi 
648*f65a228fSRobert Mustacchi static boolean_t
memstream_check_seek(FILE * f,size_t len,int whence)649*f65a228fSRobert Mustacchi memstream_check_seek(FILE *f, size_t len, int whence)
650*f65a228fSRobert Mustacchi {
651*f65a228fSRobert Mustacchi 	off_t o;
652*f65a228fSRobert Mustacchi 	long l;
653*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
654*f65a228fSRobert Mustacchi 
655*f65a228fSRobert Mustacchi 	if (fseeko(f, 0, whence) != 0) {
656*f65a228fSRobert Mustacchi 		warn("failed to seek, whence: %d", whence);
657*f65a228fSRobert Mustacchi 		return (B_FALSE);
658*f65a228fSRobert Mustacchi 	}
659*f65a228fSRobert Mustacchi 
660*f65a228fSRobert Mustacchi 	if ((o = ftello(f)) == -1) {
661*f65a228fSRobert Mustacchi 		warn("failed to get offset from ftello");
662*f65a228fSRobert Mustacchi 		ret = B_FALSE;
663*f65a228fSRobert Mustacchi 	} else if (o < 0 || (size_t)o != len) {
664*f65a228fSRobert Mustacchi 		warnx("found bad stream position: expected %zu, found: %zu",
665*f65a228fSRobert Mustacchi 		    len, (size_t)o);
666*f65a228fSRobert Mustacchi 		ret = B_FALSE;
667*f65a228fSRobert Mustacchi 	}
668*f65a228fSRobert Mustacchi 
669*f65a228fSRobert Mustacchi 	if ((l = ftell(f)) == -1) {
670*f65a228fSRobert Mustacchi 		warn("failed to get offset from ftell");
671*f65a228fSRobert Mustacchi 		ret = B_FALSE;
672*f65a228fSRobert Mustacchi 	} else if (l < 0 || (size_t)l != len) {
673*f65a228fSRobert Mustacchi 		warnx("found bad stream position: expected %zu, found: %zu",
674*f65a228fSRobert Mustacchi 		    len, (size_t)l);
675*f65a228fSRobert Mustacchi 		ret = B_FALSE;
676*f65a228fSRobert Mustacchi 	}
677*f65a228fSRobert Mustacchi 
678*f65a228fSRobert Mustacchi 	return (ret);
679*f65a228fSRobert Mustacchi }
680*f65a228fSRobert Mustacchi 
681*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_r(void)682*f65a228fSRobert Mustacchi fmemopen_defseek_r(void)
683*f65a228fSRobert Mustacchi {
684*f65a228fSRobert Mustacchi 	FILE *f;
685*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
686*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
687*f65a228fSRobert Mustacchi 
688*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
689*f65a228fSRobert Mustacchi 	if (f == NULL) {
690*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
691*f65a228fSRobert Mustacchi 		return (B_FALSE);
692*f65a228fSRobert Mustacchi 	}
693*f65a228fSRobert Mustacchi 
694*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
695*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_END);
696*f65a228fSRobert Mustacchi 	(void) fclose(f);
697*f65a228fSRobert Mustacchi 	return (ret && ret2);
698*f65a228fSRobert Mustacchi }
699*f65a228fSRobert Mustacchi 
700*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_rp(void)701*f65a228fSRobert Mustacchi fmemopen_defseek_rp(void)
702*f65a228fSRobert Mustacchi {
703*f65a228fSRobert Mustacchi 	FILE *f;
704*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
705*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
706*f65a228fSRobert Mustacchi 
707*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r+");
708*f65a228fSRobert Mustacchi 	if (f == NULL) {
709*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
710*f65a228fSRobert Mustacchi 		return (B_FALSE);
711*f65a228fSRobert Mustacchi 	}
712*f65a228fSRobert Mustacchi 
713*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
714*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_END);
715*f65a228fSRobert Mustacchi 	(void) fclose(f);
716*f65a228fSRobert Mustacchi 	return (ret && ret2);
717*f65a228fSRobert Mustacchi }
718*f65a228fSRobert Mustacchi 
719*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_w(void)720*f65a228fSRobert Mustacchi fmemopen_defseek_w(void)
721*f65a228fSRobert Mustacchi {
722*f65a228fSRobert Mustacchi 	FILE *f;
723*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
724*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
725*f65a228fSRobert Mustacchi 	char *str;
726*f65a228fSRobert Mustacchi 
727*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
728*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
729*f65a228fSRobert Mustacchi 		return (B_FALSE);
730*f65a228fSRobert Mustacchi 	}
731*f65a228fSRobert Mustacchi 
732*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "w");
733*f65a228fSRobert Mustacchi 	if (f == NULL) {
734*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
735*f65a228fSRobert Mustacchi 		free(str);
736*f65a228fSRobert Mustacchi 		return (B_FALSE);
737*f65a228fSRobert Mustacchi 	}
738*f65a228fSRobert Mustacchi 
739*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
740*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 0, SEEK_END);
741*f65a228fSRobert Mustacchi 	(void) fclose(f);
742*f65a228fSRobert Mustacchi 	free(str);
743*f65a228fSRobert Mustacchi 	return (ret && ret2);
744*f65a228fSRobert Mustacchi }
745*f65a228fSRobert Mustacchi 
746*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_wp(void)747*f65a228fSRobert Mustacchi fmemopen_defseek_wp(void)
748*f65a228fSRobert Mustacchi {
749*f65a228fSRobert Mustacchi 	FILE *f;
750*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
751*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
752*f65a228fSRobert Mustacchi 	char *str;
753*f65a228fSRobert Mustacchi 
754*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
755*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
756*f65a228fSRobert Mustacchi 		return (B_FALSE);
757*f65a228fSRobert Mustacchi 	}
758*f65a228fSRobert Mustacchi 
759*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "w+");
760*f65a228fSRobert Mustacchi 	if (f == NULL) {
761*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
762*f65a228fSRobert Mustacchi 		free(str);
763*f65a228fSRobert Mustacchi 		return (B_FALSE);
764*f65a228fSRobert Mustacchi 	}
765*f65a228fSRobert Mustacchi 
766*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
767*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 0, SEEK_END);
768*f65a228fSRobert Mustacchi 	(void) fclose(f);
769*f65a228fSRobert Mustacchi 	free(str);
770*f65a228fSRobert Mustacchi 	return (ret && ret2);
771*f65a228fSRobert Mustacchi }
772*f65a228fSRobert Mustacchi 
773*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_a(void)774*f65a228fSRobert Mustacchi fmemopen_defseek_a(void)
775*f65a228fSRobert Mustacchi {
776*f65a228fSRobert Mustacchi 	FILE *f;
777*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
778*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
779*f65a228fSRobert Mustacchi 	char *str;
780*f65a228fSRobert Mustacchi 
781*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
782*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
783*f65a228fSRobert Mustacchi 		return (B_FALSE);
784*f65a228fSRobert Mustacchi 	}
785*f65a228fSRobert Mustacchi 
786*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "a");
787*f65a228fSRobert Mustacchi 	if (f == NULL) {
788*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
789*f65a228fSRobert Mustacchi 		free(str);
790*f65a228fSRobert Mustacchi 		return (B_FALSE);
791*f65a228fSRobert Mustacchi 	}
792*f65a228fSRobert Mustacchi 
793*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, len, SEEK_CUR);
794*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_END);
795*f65a228fSRobert Mustacchi 	(void) fclose(f);
796*f65a228fSRobert Mustacchi 	free(str);
797*f65a228fSRobert Mustacchi 	return (ret && ret2);
798*f65a228fSRobert Mustacchi }
799*f65a228fSRobert Mustacchi 
800*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_ap(void)801*f65a228fSRobert Mustacchi fmemopen_defseek_ap(void)
802*f65a228fSRobert Mustacchi {
803*f65a228fSRobert Mustacchi 	FILE *f;
804*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
805*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
806*f65a228fSRobert Mustacchi 	char *str;
807*f65a228fSRobert Mustacchi 
808*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
809*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
810*f65a228fSRobert Mustacchi 		return (B_FALSE);
811*f65a228fSRobert Mustacchi 	}
812*f65a228fSRobert Mustacchi 
813*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "a+");
814*f65a228fSRobert Mustacchi 	if (f == NULL) {
815*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
816*f65a228fSRobert Mustacchi 		free(str);
817*f65a228fSRobert Mustacchi 		return (B_FALSE);
818*f65a228fSRobert Mustacchi 	}
819*f65a228fSRobert Mustacchi 
820*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, len, SEEK_CUR);
821*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_END);
822*f65a228fSRobert Mustacchi 	(void) fclose(f);
823*f65a228fSRobert Mustacchi 	free(str);
824*f65a228fSRobert Mustacchi 	return (ret && ret2);
825*f65a228fSRobert Mustacchi }
826*f65a228fSRobert Mustacchi 
827*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_a_nbyte(void)828*f65a228fSRobert Mustacchi fmemopen_defseek_a_nbyte(void)
829*f65a228fSRobert Mustacchi {
830*f65a228fSRobert Mustacchi 	FILE *f;
831*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
832*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
833*f65a228fSRobert Mustacchi 	char *str;
834*f65a228fSRobert Mustacchi 
835*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
836*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
837*f65a228fSRobert Mustacchi 		return (B_FALSE);
838*f65a228fSRobert Mustacchi 	}
839*f65a228fSRobert Mustacchi 	str[8] = '\0';
840*f65a228fSRobert Mustacchi 
841*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "a");
842*f65a228fSRobert Mustacchi 	if (f == NULL) {
843*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
844*f65a228fSRobert Mustacchi 		free(str);
845*f65a228fSRobert Mustacchi 		return (B_FALSE);
846*f65a228fSRobert Mustacchi 	}
847*f65a228fSRobert Mustacchi 
848*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 8, SEEK_CUR);
849*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 8, SEEK_END);
850*f65a228fSRobert Mustacchi 	(void) fclose(f);
851*f65a228fSRobert Mustacchi 	free(str);
852*f65a228fSRobert Mustacchi 	return (ret && ret2);
853*f65a228fSRobert Mustacchi }
854*f65a228fSRobert Mustacchi 
855*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_ap_nbyte(void)856*f65a228fSRobert Mustacchi fmemopen_defseek_ap_nbyte(void)
857*f65a228fSRobert Mustacchi {
858*f65a228fSRobert Mustacchi 	FILE *f;
859*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
860*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
861*f65a228fSRobert Mustacchi 	char *str;
862*f65a228fSRobert Mustacchi 
863*f65a228fSRobert Mustacchi 	if ((str = strdup(fmemopen_str1)) == NULL) {
864*f65a228fSRobert Mustacchi 		warn("failed to duplicate string");
865*f65a228fSRobert Mustacchi 		return (B_FALSE);
866*f65a228fSRobert Mustacchi 	}
867*f65a228fSRobert Mustacchi 	str[12] = '\0';
868*f65a228fSRobert Mustacchi 
869*f65a228fSRobert Mustacchi 	f = fmemopen(str, len, "a+");
870*f65a228fSRobert Mustacchi 	if (f == NULL) {
871*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
872*f65a228fSRobert Mustacchi 		free(str);
873*f65a228fSRobert Mustacchi 		return (B_FALSE);
874*f65a228fSRobert Mustacchi 	}
875*f65a228fSRobert Mustacchi 
876*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 12, SEEK_CUR);
877*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 12, SEEK_END);
878*f65a228fSRobert Mustacchi 	(void) fclose(f);
879*f65a228fSRobert Mustacchi 	free(str);
880*f65a228fSRobert Mustacchi 	return (ret && ret2);
881*f65a228fSRobert Mustacchi }
882*f65a228fSRobert Mustacchi 
883*f65a228fSRobert Mustacchi static boolean_t
fmemopen_defseek_ap_null(void)884*f65a228fSRobert Mustacchi fmemopen_defseek_ap_null(void)
885*f65a228fSRobert Mustacchi {
886*f65a228fSRobert Mustacchi 	FILE *f;
887*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
888*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
889*f65a228fSRobert Mustacchi 
890*f65a228fSRobert Mustacchi 	f = fmemopen(NULL, len, "a+");
891*f65a228fSRobert Mustacchi 	if (f == NULL) {
892*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
893*f65a228fSRobert Mustacchi 		return (B_FALSE);
894*f65a228fSRobert Mustacchi 	}
895*f65a228fSRobert Mustacchi 
896*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
897*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 0, SEEK_END);
898*f65a228fSRobert Mustacchi 	(void) fclose(f);
899*f65a228fSRobert Mustacchi 	return (ret && ret2);
900*f65a228fSRobert Mustacchi }
901*f65a228fSRobert Mustacchi 
902*f65a228fSRobert Mustacchi static boolean_t
fmemopen_read_eof_fgetc(void)903*f65a228fSRobert Mustacchi fmemopen_read_eof_fgetc(void)
904*f65a228fSRobert Mustacchi {
905*f65a228fSRobert Mustacchi 	FILE *f;
906*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
907*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE, ret2, ret3;
908*f65a228fSRobert Mustacchi 
909*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
910*f65a228fSRobert Mustacchi 	if (f == NULL) {
911*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
912*f65a228fSRobert Mustacchi 		return (B_FALSE);
913*f65a228fSRobert Mustacchi 	}
914*f65a228fSRobert Mustacchi 
915*f65a228fSRobert Mustacchi 	while (fgetc(f) != EOF) {
916*f65a228fSRobert Mustacchi 		continue;
917*f65a228fSRobert Mustacchi 	}
918*f65a228fSRobert Mustacchi 
919*f65a228fSRobert Mustacchi 	if (feof(f) == 0) {
920*f65a228fSRobert Mustacchi 		warnx("stream not at end of EOF");
921*f65a228fSRobert Mustacchi 		ret = B_FALSE;
922*f65a228fSRobert Mustacchi 	}
923*f65a228fSRobert Mustacchi 
924*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_CUR);
925*f65a228fSRobert Mustacchi 	ret3 = memstream_check_seek(f, len, SEEK_END);
926*f65a228fSRobert Mustacchi 	(void) fclose(f);
927*f65a228fSRobert Mustacchi 	return (ret && ret2 && ret3);
928*f65a228fSRobert Mustacchi }
929*f65a228fSRobert Mustacchi 
930*f65a228fSRobert Mustacchi static boolean_t
fmemopen_read_eof_fgets(void)931*f65a228fSRobert Mustacchi fmemopen_read_eof_fgets(void)
932*f65a228fSRobert Mustacchi {
933*f65a228fSRobert Mustacchi 	FILE *f;
934*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
935*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE, ret2, ret3;
936*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
937*f65a228fSRobert Mustacchi 
938*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
939*f65a228fSRobert Mustacchi 	if (f == NULL) {
940*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
941*f65a228fSRobert Mustacchi 		return (B_FALSE);
942*f65a228fSRobert Mustacchi 	}
943*f65a228fSRobert Mustacchi 
944*f65a228fSRobert Mustacchi 	while (fgets(buf, sizeof (buf), f) != NULL) {
945*f65a228fSRobert Mustacchi 		continue;
946*f65a228fSRobert Mustacchi 	}
947*f65a228fSRobert Mustacchi 
948*f65a228fSRobert Mustacchi 	if (feof(f) == 0) {
949*f65a228fSRobert Mustacchi 		warnx("stream not at end of EOF");
950*f65a228fSRobert Mustacchi 		ret = B_FALSE;
951*f65a228fSRobert Mustacchi 	}
952*f65a228fSRobert Mustacchi 
953*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_CUR);
954*f65a228fSRobert Mustacchi 	ret3 = memstream_check_seek(f, len, SEEK_END);
955*f65a228fSRobert Mustacchi 	(void) fclose(f);
956*f65a228fSRobert Mustacchi 	return (ret && ret2 && ret3);
957*f65a228fSRobert Mustacchi }
958*f65a228fSRobert Mustacchi 
959*f65a228fSRobert Mustacchi static boolean_t
fmemopen_read_eof_fread(void)960*f65a228fSRobert Mustacchi fmemopen_read_eof_fread(void)
961*f65a228fSRobert Mustacchi {
962*f65a228fSRobert Mustacchi 	FILE *f;
963*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
964*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE, ret2, ret3;
965*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
966*f65a228fSRobert Mustacchi 
967*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
968*f65a228fSRobert Mustacchi 	if (f == NULL) {
969*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
970*f65a228fSRobert Mustacchi 		return (B_FALSE);
971*f65a228fSRobert Mustacchi 	}
972*f65a228fSRobert Mustacchi 
973*f65a228fSRobert Mustacchi 	while (fread(buf, sizeof (buf), 1, f) != 0) {
974*f65a228fSRobert Mustacchi 		continue;
975*f65a228fSRobert Mustacchi 	}
976*f65a228fSRobert Mustacchi 
977*f65a228fSRobert Mustacchi 	if (feof(f) == 0) {
978*f65a228fSRobert Mustacchi 		warnx("stream not at end of EOF");
979*f65a228fSRobert Mustacchi 		ret = B_FALSE;
980*f65a228fSRobert Mustacchi 	}
981*f65a228fSRobert Mustacchi 
982*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_CUR);
983*f65a228fSRobert Mustacchi 	ret3 = memstream_check_seek(f, len, SEEK_END);
984*f65a228fSRobert Mustacchi 	(void) fclose(f);
985*f65a228fSRobert Mustacchi 	return (ret && ret2 && ret3);
986*f65a228fSRobert Mustacchi }
987*f65a228fSRobert Mustacchi 
988*f65a228fSRobert Mustacchi static boolean_t
fmemopen_read_eof_fread2(void)989*f65a228fSRobert Mustacchi fmemopen_read_eof_fread2(void)
990*f65a228fSRobert Mustacchi {
991*f65a228fSRobert Mustacchi 	FILE *f;
992*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
993*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE, ret2, ret3;
994*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
995*f65a228fSRobert Mustacchi 
996*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
997*f65a228fSRobert Mustacchi 	if (f == NULL) {
998*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
999*f65a228fSRobert Mustacchi 		return (B_FALSE);
1000*f65a228fSRobert Mustacchi 	}
1001*f65a228fSRobert Mustacchi 
1002*f65a228fSRobert Mustacchi 	while (fread(buf, 1, sizeof (buf), f) != 0) {
1003*f65a228fSRobert Mustacchi 		continue;
1004*f65a228fSRobert Mustacchi 	}
1005*f65a228fSRobert Mustacchi 
1006*f65a228fSRobert Mustacchi 	if (feof(f) == 0) {
1007*f65a228fSRobert Mustacchi 		warnx("stream not at end of EOF");
1008*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1009*f65a228fSRobert Mustacchi 	}
1010*f65a228fSRobert Mustacchi 
1011*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, len, SEEK_CUR);
1012*f65a228fSRobert Mustacchi 	ret3 = memstream_check_seek(f, len, SEEK_END);
1013*f65a228fSRobert Mustacchi 	(void) fclose(f);
1014*f65a228fSRobert Mustacchi 	return (ret && ret2 && ret3);
1015*f65a228fSRobert Mustacchi }
1016*f65a228fSRobert Mustacchi 
1017*f65a228fSRobert Mustacchi static boolean_t
fmemopen_bad_seeks(void)1018*f65a228fSRobert Mustacchi fmemopen_bad_seeks(void)
1019*f65a228fSRobert Mustacchi {
1020*f65a228fSRobert Mustacchi 	FILE *f;
1021*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1022*f65a228fSRobert Mustacchi 	size_t len = strlen(fmemopen_str1);
1023*f65a228fSRobert Mustacchi 	uint_t i;
1024*f65a228fSRobert Mustacchi 	struct {
1025*f65a228fSRobert Mustacchi 		int ret;
1026*f65a228fSRobert Mustacchi 		int whence;
1027*f65a228fSRobert Mustacchi 		long off;
1028*f65a228fSRobert Mustacchi 		long newpos;
1029*f65a228fSRobert Mustacchi 	} seeks[] = {
1030*f65a228fSRobert Mustacchi 		{ 0, SEEK_CUR, 0, 0 },
1031*f65a228fSRobert Mustacchi 		{ -1, SEEK_CUR, -1, 0 },
1032*f65a228fSRobert Mustacchi 		{ -1, SEEK_SET, -5, 0 },
1033*f65a228fSRobert Mustacchi 		{ -1, SEEK_END, -128, 0 },
1034*f65a228fSRobert Mustacchi 		{ -1, SEEK_END, 1, 0 },
1035*f65a228fSRobert Mustacchi 		{ -1, SEEK_SET, 128, 0 },
1036*f65a228fSRobert Mustacchi 		{ 0, SEEK_SET, 16, 16 },
1037*f65a228fSRobert Mustacchi 		{ -1, SEEK_CUR, -20, 16 },
1038*f65a228fSRobert Mustacchi 		{ 0, SEEK_CUR, -16, 0 },
1039*f65a228fSRobert Mustacchi 	};
1040*f65a228fSRobert Mustacchi 
1041*f65a228fSRobert Mustacchi 	f = fmemopen(fmemopen_str1, len, "r");
1042*f65a228fSRobert Mustacchi 	if (f == NULL) {
1043*f65a228fSRobert Mustacchi 		warn("failed to open fmemopen stream");
1044*f65a228fSRobert Mustacchi 		return (B_FALSE);
1045*f65a228fSRobert Mustacchi 	}
1046*f65a228fSRobert Mustacchi 
1047*f65a228fSRobert Mustacchi 	for (i = 0; i < ARRAY_SIZE(seeks); i++) {
1048*f65a228fSRobert Mustacchi 		int r;
1049*f65a228fSRobert Mustacchi 
1050*f65a228fSRobert Mustacchi 		r = fseek(f, seeks[i].off, seeks[i].whence);
1051*f65a228fSRobert Mustacchi 		if (r != seeks[i].ret) {
1052*f65a228fSRobert Mustacchi 			warnx("found bad return value for seek %d/%ld, "
1053*f65a228fSRobert Mustacchi 			    "expected %d, found %d", seeks[i].whence,
1054*f65a228fSRobert Mustacchi 			    seeks[i].off, seeks[i].ret, r);
1055*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1056*f65a228fSRobert Mustacchi 		}
1057*f65a228fSRobert Mustacchi 
1058*f65a228fSRobert Mustacchi 		ret &= memstream_check_seek(f, seeks[i].newpos, SEEK_CUR);
1059*f65a228fSRobert Mustacchi 	}
1060*f65a228fSRobert Mustacchi 
1061*f65a228fSRobert Mustacchi 	(void) fclose(f);
1062*f65a228fSRobert Mustacchi 	return (ret);
1063*f65a228fSRobert Mustacchi }
1064*f65a228fSRobert Mustacchi 
1065*f65a228fSRobert Mustacchi static boolean_t
fmemopen_open_trunc(void)1066*f65a228fSRobert Mustacchi fmemopen_open_trunc(void)
1067*f65a228fSRobert Mustacchi {
1068*f65a228fSRobert Mustacchi 	char buf[16];
1069*f65a228fSRobert Mustacchi 	FILE *f;
1070*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1071*f65a228fSRobert Mustacchi 
1072*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
1073*f65a228fSRobert Mustacchi 	f = fmemopen(buf, sizeof (buf), "w+");
1074*f65a228fSRobert Mustacchi 	if (f == NULL) {
1075*f65a228fSRobert Mustacchi 		warn("failed to create fmemopen stream");
1076*f65a228fSRobert Mustacchi 		return (B_FALSE);
1077*f65a228fSRobert Mustacchi 	}
1078*f65a228fSRobert Mustacchi 
1079*f65a228fSRobert Mustacchi 	if (buf[0] != '\0') {
1080*f65a228fSRobert Mustacchi 		warnx("w+ mode didn't truncate the buffer");
1081*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1082*f65a228fSRobert Mustacchi 	}
1083*f65a228fSRobert Mustacchi 
1084*f65a228fSRobert Mustacchi 	(void) fclose(f);
1085*f65a228fSRobert Mustacchi 	return (ret);
1086*f65a228fSRobert Mustacchi }
1087*f65a228fSRobert Mustacchi 
1088*f65a228fSRobert Mustacchi static boolean_t
fmemopen_write_nul(void)1089*f65a228fSRobert Mustacchi fmemopen_write_nul(void)
1090*f65a228fSRobert Mustacchi {
1091*f65a228fSRobert Mustacchi 	char buf[BUFSIZ];
1092*f65a228fSRobert Mustacchi 	FILE *f;
1093*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1094*f65a228fSRobert Mustacchi 	size_t npos = sizeof (buf) - 32;
1095*f65a228fSRobert Mustacchi 
1096*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
1097*f65a228fSRobert Mustacchi 
1098*f65a228fSRobert Mustacchi 	f = fmemopen(buf, sizeof (buf), "w");
1099*f65a228fSRobert Mustacchi 	if (f == NULL) {
1100*f65a228fSRobert Mustacchi 		warn("failed to create fmemopen stream");
1101*f65a228fSRobert Mustacchi 		return (B_FALSE);
1102*f65a228fSRobert Mustacchi 	}
1103*f65a228fSRobert Mustacchi 
1104*f65a228fSRobert Mustacchi 	if (fputc('b', f) != 'b') {
1105*f65a228fSRobert Mustacchi 		warn("failed to write 'b' character to stream");
1106*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1107*f65a228fSRobert Mustacchi 	}
1108*f65a228fSRobert Mustacchi 
1109*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1110*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1111*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1112*f65a228fSRobert Mustacchi 	}
1113*f65a228fSRobert Mustacchi 
1114*f65a228fSRobert Mustacchi 	if (buf[0] != 'b' || buf[1] != '\0') {
1115*f65a228fSRobert Mustacchi 		warn("stream didn't properly write character and nul");
1116*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1117*f65a228fSRobert Mustacchi 	}
1118*f65a228fSRobert Mustacchi 
1119*f65a228fSRobert Mustacchi 	if (fseek(f, sizeof (buf) - 32, SEEK_SET)) {
1120*f65a228fSRobert Mustacchi 		warn("failed to seek stream");
1121*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1122*f65a228fSRobert Mustacchi 	}
1123*f65a228fSRobert Mustacchi 
1124*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1125*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1126*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1127*f65a228fSRobert Mustacchi 	}
1128*f65a228fSRobert Mustacchi 
1129*f65a228fSRobert Mustacchi 	if (buf[npos] != 'a' || buf[npos - 1] != 'a' ||
1130*f65a228fSRobert Mustacchi 	    buf[npos + 1] != 'a') {
1131*f65a228fSRobert Mustacchi 		warnx("seeking incorrectly inserted a nul");
1132*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1133*f65a228fSRobert Mustacchi 	}
1134*f65a228fSRobert Mustacchi 
1135*f65a228fSRobert Mustacchi 	(void) fclose(f);
1136*f65a228fSRobert Mustacchi 
1137*f65a228fSRobert Mustacchi 	if (buf[npos] != 'a' || buf[npos - 1] != 'a' ||
1138*f65a228fSRobert Mustacchi 	    buf[npos + 1] != 'a') {
1139*f65a228fSRobert Mustacchi 		warnx("seeking incorrectly inserted a nul");
1140*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1141*f65a228fSRobert Mustacchi 	}
1142*f65a228fSRobert Mustacchi 
1143*f65a228fSRobert Mustacchi 	return (ret);
1144*f65a228fSRobert Mustacchi }
1145*f65a228fSRobert Mustacchi 
1146*f65a228fSRobert Mustacchi static boolean_t
fmemopen_append_nul(void)1147*f65a228fSRobert Mustacchi fmemopen_append_nul(void)
1148*f65a228fSRobert Mustacchi {
1149*f65a228fSRobert Mustacchi 	char buf[32], buf2[32];
1150*f65a228fSRobert Mustacchi 	FILE *f;
1151*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1152*f65a228fSRobert Mustacchi 
1153*f65a228fSRobert Mustacchi 	(void) memset(buf, 'a', sizeof (buf));
1154*f65a228fSRobert Mustacchi 	buf[8] = '\0';
1155*f65a228fSRobert Mustacchi 
1156*f65a228fSRobert Mustacchi 	f = fmemopen(buf, sizeof (buf), "a");
1157*f65a228fSRobert Mustacchi 	if (f == NULL) {
1158*f65a228fSRobert Mustacchi 		warn("failed to create fmemopen stream");
1159*f65a228fSRobert Mustacchi 		return (B_FALSE);
1160*f65a228fSRobert Mustacchi 	}
1161*f65a228fSRobert Mustacchi 
1162*f65a228fSRobert Mustacchi 	if (fputc('b', f) != 'b') {
1163*f65a228fSRobert Mustacchi 		warn("failed to write 'b' character to stream");
1164*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1165*f65a228fSRobert Mustacchi 	}
1166*f65a228fSRobert Mustacchi 
1167*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1168*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1169*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1170*f65a228fSRobert Mustacchi 	}
1171*f65a228fSRobert Mustacchi 
1172*f65a228fSRobert Mustacchi 	if (buf[8] != 'b' || buf[9] != '\0') {
1173*f65a228fSRobert Mustacchi 		warn("stream didn't properly write character and nul");
1174*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1175*f65a228fSRobert Mustacchi 	}
1176*f65a228fSRobert Mustacchi 
1177*f65a228fSRobert Mustacchi 	/*
1178*f65a228fSRobert Mustacchi 	 * Append mode shouldn't insert a NUL if we write the entire buffer.
1179*f65a228fSRobert Mustacchi 	 */
1180*f65a228fSRobert Mustacchi 	(void) memset(buf2, 'b', sizeof (buf2));
1181*f65a228fSRobert Mustacchi 	if (fwrite(buf2, sizeof (buf2) - ftell(f), 1, f) != 1) {
1182*f65a228fSRobert Mustacchi 		warn("failed to write buf2");
1183*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1184*f65a228fSRobert Mustacchi 	}
1185*f65a228fSRobert Mustacchi 
1186*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1187*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1188*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1189*f65a228fSRobert Mustacchi 	}
1190*f65a228fSRobert Mustacchi 
1191*f65a228fSRobert Mustacchi 	if (buf[sizeof (buf) - 1] != 'b') {
1192*f65a228fSRobert Mustacchi 		warnx("found invalid character: %x", buf[sizeof (buf) - 1]);
1193*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1194*f65a228fSRobert Mustacchi 	}
1195*f65a228fSRobert Mustacchi 
1196*f65a228fSRobert Mustacchi 	(void) fclose(f);
1197*f65a228fSRobert Mustacchi 
1198*f65a228fSRobert Mustacchi 	if (buf[sizeof (buf) - 1] != 'b') {
1199*f65a228fSRobert Mustacchi 		warnx("found invalid character: %x", buf[sizeof (buf) - 1]);
1200*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1201*f65a228fSRobert Mustacchi 	}
1202*f65a228fSRobert Mustacchi 
1203*f65a228fSRobert Mustacchi 	return (ret);
1204*f65a228fSRobert Mustacchi }
1205*f65a228fSRobert Mustacchi 
1206*f65a228fSRobert Mustacchi static boolean_t
fmemopen_read_nul(void)1207*f65a228fSRobert Mustacchi fmemopen_read_nul(void)
1208*f65a228fSRobert Mustacchi {
1209*f65a228fSRobert Mustacchi 	char buf[32];
1210*f65a228fSRobert Mustacchi 	FILE *f;
1211*f65a228fSRobert Mustacchi 
1212*f65a228fSRobert Mustacchi 	(void) memset(buf, '\0', sizeof (buf));
1213*f65a228fSRobert Mustacchi 
1214*f65a228fSRobert Mustacchi 	f = fmemopen(buf, sizeof (buf), "r+");
1215*f65a228fSRobert Mustacchi 	if (f == NULL) {
1216*f65a228fSRobert Mustacchi 		warn("failed to create fmemopen stream");
1217*f65a228fSRobert Mustacchi 		return (B_FALSE);
1218*f65a228fSRobert Mustacchi 	}
1219*f65a228fSRobert Mustacchi 
1220*f65a228fSRobert Mustacchi 	if (fgetc(f) != '\0') {
1221*f65a228fSRobert Mustacchi 		warnx("failed to read nul character");
1222*f65a228fSRobert Mustacchi 		return (B_FALSE);
1223*f65a228fSRobert Mustacchi 	}
1224*f65a228fSRobert Mustacchi 
1225*f65a228fSRobert Mustacchi 	(void) fclose(f);
1226*f65a228fSRobert Mustacchi 	return (B_TRUE);
1227*f65a228fSRobert Mustacchi }
1228*f65a228fSRobert Mustacchi 
1229*f65a228fSRobert Mustacchi static boolean_t
open_memstream_def_seek(void)1230*f65a228fSRobert Mustacchi open_memstream_def_seek(void)
1231*f65a228fSRobert Mustacchi {
1232*f65a228fSRobert Mustacchi 	char *c;
1233*f65a228fSRobert Mustacchi 	size_t s;
1234*f65a228fSRobert Mustacchi 	FILE *f;
1235*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
1236*f65a228fSRobert Mustacchi 
1237*f65a228fSRobert Mustacchi 	if ((f = open_memstream(&c, &s)) == NULL) {
1238*f65a228fSRobert Mustacchi 		warn("failed to call open_memstream()");
1239*f65a228fSRobert Mustacchi 		return (B_FALSE);
1240*f65a228fSRobert Mustacchi 	}
1241*f65a228fSRobert Mustacchi 
1242*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
1243*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 0, SEEK_END);
1244*f65a228fSRobert Mustacchi 	(void) fclose(f);
1245*f65a228fSRobert Mustacchi 	free(c);
1246*f65a228fSRobert Mustacchi 	return (ret && ret2);
1247*f65a228fSRobert Mustacchi }
1248*f65a228fSRobert Mustacchi 
1249*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_def_seek(void)1250*f65a228fSRobert Mustacchi open_wmemstream_def_seek(void)
1251*f65a228fSRobert Mustacchi {
1252*f65a228fSRobert Mustacchi 	wchar_t *c;
1253*f65a228fSRobert Mustacchi 	size_t s;
1254*f65a228fSRobert Mustacchi 	FILE *f;
1255*f65a228fSRobert Mustacchi 	boolean_t ret, ret2;
1256*f65a228fSRobert Mustacchi 
1257*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1258*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1259*f65a228fSRobert Mustacchi 		return (B_FALSE);
1260*f65a228fSRobert Mustacchi 	}
1261*f65a228fSRobert Mustacchi 
1262*f65a228fSRobert Mustacchi 	ret = memstream_check_seek(f, 0, SEEK_CUR);
1263*f65a228fSRobert Mustacchi 	ret2 = memstream_check_seek(f, 0, SEEK_END);
1264*f65a228fSRobert Mustacchi 	(void) fclose(f);
1265*f65a228fSRobert Mustacchi 	free(c);
1266*f65a228fSRobert Mustacchi 	return (ret && ret2);
1267*f65a228fSRobert Mustacchi }
1268*f65a228fSRobert Mustacchi 
1269*f65a228fSRobert Mustacchi static boolean_t
open_memstream_no_read(void)1270*f65a228fSRobert Mustacchi open_memstream_no_read(void)
1271*f65a228fSRobert Mustacchi {
1272*f65a228fSRobert Mustacchi 	char *c;
1273*f65a228fSRobert Mustacchi 	size_t s;
1274*f65a228fSRobert Mustacchi 	FILE *f;
1275*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1276*f65a228fSRobert Mustacchi 
1277*f65a228fSRobert Mustacchi 	if ((f = open_memstream(&c, &s)) == NULL) {
1278*f65a228fSRobert Mustacchi 		warn("failed to call open_memstream()");
1279*f65a228fSRobert Mustacchi 		return (B_FALSE);
1280*f65a228fSRobert Mustacchi 	}
1281*f65a228fSRobert Mustacchi 
1282*f65a228fSRobert Mustacchi 	if (fgetc(f) != EOF) {
1283*f65a228fSRobert Mustacchi 		warnx("read succeeded when it should have failed");
1284*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1285*f65a228fSRobert Mustacchi 	}
1286*f65a228fSRobert Mustacchi 
1287*f65a228fSRobert Mustacchi 	if (errno != EBADF) {
1288*f65a228fSRobert Mustacchi 		warnx("found wrong errno, expected %d, found %d", EBADF, errno);
1289*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1290*f65a228fSRobert Mustacchi 	}
1291*f65a228fSRobert Mustacchi 
1292*f65a228fSRobert Mustacchi 	(void) fclose(f);
1293*f65a228fSRobert Mustacchi 	free(c);
1294*f65a228fSRobert Mustacchi 	return (ret);
1295*f65a228fSRobert Mustacchi }
1296*f65a228fSRobert Mustacchi 
1297*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_no_read(void)1298*f65a228fSRobert Mustacchi open_wmemstream_no_read(void)
1299*f65a228fSRobert Mustacchi {
1300*f65a228fSRobert Mustacchi 	wchar_t *c;
1301*f65a228fSRobert Mustacchi 	size_t s;
1302*f65a228fSRobert Mustacchi 	FILE *f;
1303*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1304*f65a228fSRobert Mustacchi 
1305*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1306*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1307*f65a228fSRobert Mustacchi 		return (B_FALSE);
1308*f65a228fSRobert Mustacchi 	}
1309*f65a228fSRobert Mustacchi 
1310*f65a228fSRobert Mustacchi 	if (fgetc(f) != EOF) {
1311*f65a228fSRobert Mustacchi 		warnx("read succeeded when it should have failed");
1312*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1313*f65a228fSRobert Mustacchi 	}
1314*f65a228fSRobert Mustacchi 
1315*f65a228fSRobert Mustacchi 	if (errno != EBADF) {
1316*f65a228fSRobert Mustacchi 		warnx("found wrong errno, expected %d, found %d", EBADF, errno);
1317*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1318*f65a228fSRobert Mustacchi 	}
1319*f65a228fSRobert Mustacchi 
1320*f65a228fSRobert Mustacchi 	(void) fclose(f);
1321*f65a228fSRobert Mustacchi 	free(c);
1322*f65a228fSRobert Mustacchi 	return (ret);
1323*f65a228fSRobert Mustacchi }
1324*f65a228fSRobert Mustacchi 
1325*f65a228fSRobert Mustacchi static boolean_t
open_memstream_bad_flush(void)1326*f65a228fSRobert Mustacchi open_memstream_bad_flush(void)
1327*f65a228fSRobert Mustacchi {
1328*f65a228fSRobert Mustacchi 	char *c;
1329*f65a228fSRobert Mustacchi 	size_t s;
1330*f65a228fSRobert Mustacchi 	FILE *f;
1331*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1332*f65a228fSRobert Mustacchi 
1333*f65a228fSRobert Mustacchi 	if ((f = open_memstream(&c, &s)) == NULL) {
1334*f65a228fSRobert Mustacchi 		warn("failed to call open_memstream()");
1335*f65a228fSRobert Mustacchi 		return (B_FALSE);
1336*f65a228fSRobert Mustacchi 	}
1337*f65a228fSRobert Mustacchi 
1338*f65a228fSRobert Mustacchi 	/* Force the buffer to exist */
1339*f65a228fSRobert Mustacchi 	if (fputc('a', f) != 'a') {
1340*f65a228fSRobert Mustacchi 		warn("failed to write character to buffer");
1341*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1342*f65a228fSRobert Mustacchi 	}
1343*f65a228fSRobert Mustacchi 
1344*f65a228fSRobert Mustacchi 	if (fseek(f, BUFSIZ * 2 + 1, SEEK_END) != 0) {
1345*f65a228fSRobert Mustacchi 		warn("Failed to seek beyond buffer size");
1346*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1347*f65a228fSRobert Mustacchi 	}
1348*f65a228fSRobert Mustacchi 
1349*f65a228fSRobert Mustacchi 	umem_setmtbf(1);
1350*f65a228fSRobert Mustacchi 	if (fputc('a', f) != 'a') {
1351*f65a228fSRobert Mustacchi 		warn("failed to write character to buffer");
1352*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1353*f65a228fSRobert Mustacchi 	}
1354*f65a228fSRobert Mustacchi 
1355*f65a228fSRobert Mustacchi 	if (fflush(f) != EOF) {
1356*f65a228fSRobert Mustacchi 		warnx("fflush succeeded when it should have failed");
1357*f65a228fSRobert Mustacchi 	}
1358*f65a228fSRobert Mustacchi 
1359*f65a228fSRobert Mustacchi 	if (errno != EAGAIN) {
1360*f65a228fSRobert Mustacchi 		warnx("bad errno, found %d, expected %d", errno, EAGAIN);
1361*f65a228fSRobert Mustacchi 	}
1362*f65a228fSRobert Mustacchi 	umem_setmtbf(0);
1363*f65a228fSRobert Mustacchi 
1364*f65a228fSRobert Mustacchi 	(void) fclose(f);
1365*f65a228fSRobert Mustacchi 	free(c);
1366*f65a228fSRobert Mustacchi 	return (ret);
1367*f65a228fSRobert Mustacchi }
1368*f65a228fSRobert Mustacchi 
1369*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_bad_flush(void)1370*f65a228fSRobert Mustacchi open_wmemstream_bad_flush(void)
1371*f65a228fSRobert Mustacchi {
1372*f65a228fSRobert Mustacchi 	wchar_t *c;
1373*f65a228fSRobert Mustacchi 	size_t s;
1374*f65a228fSRobert Mustacchi 	FILE *f;
1375*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1376*f65a228fSRobert Mustacchi 
1377*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1378*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1379*f65a228fSRobert Mustacchi 		return (B_FALSE);
1380*f65a228fSRobert Mustacchi 	}
1381*f65a228fSRobert Mustacchi 
1382*f65a228fSRobert Mustacchi 	/* Force the buffer to exist */
1383*f65a228fSRobert Mustacchi 	if (fputwc('a', f) != 'a') {
1384*f65a228fSRobert Mustacchi 		warn("failed to write character to buffer");
1385*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1386*f65a228fSRobert Mustacchi 	}
1387*f65a228fSRobert Mustacchi 
1388*f65a228fSRobert Mustacchi 	if (fseek(f, BUFSIZ * 2 + 1, SEEK_END) != 0) {
1389*f65a228fSRobert Mustacchi 		warn("Failed to seek beyond buffer size");
1390*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1391*f65a228fSRobert Mustacchi 	}
1392*f65a228fSRobert Mustacchi 
1393*f65a228fSRobert Mustacchi 	umem_setmtbf(1);
1394*f65a228fSRobert Mustacchi 	if (fputc('a', f) != 'a') {
1395*f65a228fSRobert Mustacchi 		warn("failed to write character to buffer");
1396*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1397*f65a228fSRobert Mustacchi 	}
1398*f65a228fSRobert Mustacchi 
1399*f65a228fSRobert Mustacchi 	if (fflush(f) != EOF) {
1400*f65a228fSRobert Mustacchi 		warnx("fflush succeeded when it should have failed");
1401*f65a228fSRobert Mustacchi 	}
1402*f65a228fSRobert Mustacchi 
1403*f65a228fSRobert Mustacchi 	if (errno != EAGAIN) {
1404*f65a228fSRobert Mustacchi 		warnx("bad errno, found %d, expected %d", errno, EAGAIN);
1405*f65a228fSRobert Mustacchi 	}
1406*f65a228fSRobert Mustacchi 	umem_setmtbf(0);
1407*f65a228fSRobert Mustacchi 
1408*f65a228fSRobert Mustacchi 	(void) fclose(f);
1409*f65a228fSRobert Mustacchi 	free(c);
1410*f65a228fSRobert Mustacchi 	return (ret);
1411*f65a228fSRobert Mustacchi }
1412*f65a228fSRobert Mustacchi 
1413*f65a228fSRobert Mustacchi static boolean_t
memstream_bad_seek(void)1414*f65a228fSRobert Mustacchi memstream_bad_seek(void)
1415*f65a228fSRobert Mustacchi {
1416*f65a228fSRobert Mustacchi 	FILE *f, *fw;
1417*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1418*f65a228fSRobert Mustacchi 	uint_t i;
1419*f65a228fSRobert Mustacchi 	char *c;
1420*f65a228fSRobert Mustacchi 	wchar_t *w;
1421*f65a228fSRobert Mustacchi 	size_t s1, s2;
1422*f65a228fSRobert Mustacchi 	struct {
1423*f65a228fSRobert Mustacchi 		int ret;
1424*f65a228fSRobert Mustacchi 		int whence;
1425*f65a228fSRobert Mustacchi 		long off;
1426*f65a228fSRobert Mustacchi 		long newpos;
1427*f65a228fSRobert Mustacchi 	} seeks[] = {
1428*f65a228fSRobert Mustacchi 		{ 0, SEEK_CUR, 0, 0 },
1429*f65a228fSRobert Mustacchi 		{ -1, SEEK_CUR, -1, 0 },
1430*f65a228fSRobert Mustacchi 		{ -1, SEEK_SET, -5, 0 },
1431*f65a228fSRobert Mustacchi 		{ -1, SEEK_END, -5, 0 },
1432*f65a228fSRobert Mustacchi 		{ 0, SEEK_SET, 16, 16 },
1433*f65a228fSRobert Mustacchi 		{ -1, SEEK_CUR, -20, 16 },
1434*f65a228fSRobert Mustacchi 		{ 0, SEEK_CUR, -16, 0 },
1435*f65a228fSRobert Mustacchi 	};
1436*f65a228fSRobert Mustacchi 
1437*f65a228fSRobert Mustacchi 	f = open_memstream(&c, &s1);
1438*f65a228fSRobert Mustacchi 	fw = open_wmemstream(&w, &s2);
1439*f65a228fSRobert Mustacchi 	if (f == NULL || fw == NULL) {
1440*f65a228fSRobert Mustacchi 		warnx("failed to create memory streams");
1441*f65a228fSRobert Mustacchi 		return (B_FALSE);
1442*f65a228fSRobert Mustacchi 	}
1443*f65a228fSRobert Mustacchi 
1444*f65a228fSRobert Mustacchi 	for (i = 0; i < ARRAY_SIZE(seeks); i++) {
1445*f65a228fSRobert Mustacchi 		int r;
1446*f65a228fSRobert Mustacchi 
1447*f65a228fSRobert Mustacchi 		r = fseek(f, seeks[i].off, seeks[i].whence);
1448*f65a228fSRobert Mustacchi 		if (r != seeks[i].ret) {
1449*f65a228fSRobert Mustacchi 			warnx("found bad return value for seek %d/%ld, "
1450*f65a228fSRobert Mustacchi 			    "expected %d, found %d", seeks[i].whence,
1451*f65a228fSRobert Mustacchi 			    seeks[i].off, seeks[i].ret, r);
1452*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1453*f65a228fSRobert Mustacchi 		}
1454*f65a228fSRobert Mustacchi 
1455*f65a228fSRobert Mustacchi 		ret &= memstream_check_seek(f, seeks[i].newpos, SEEK_CUR);
1456*f65a228fSRobert Mustacchi 
1457*f65a228fSRobert Mustacchi 		r = fseek(fw, seeks[i].off, seeks[i].whence);
1458*f65a228fSRobert Mustacchi 		if (r != seeks[i].ret) {
1459*f65a228fSRobert Mustacchi 			warnx("found bad return value for seek %d/%ld, "
1460*f65a228fSRobert Mustacchi 			    "expected %d, found %d", seeks[i].whence,
1461*f65a228fSRobert Mustacchi 			    seeks[i].off, seeks[i].ret, r);
1462*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1463*f65a228fSRobert Mustacchi 		}
1464*f65a228fSRobert Mustacchi 
1465*f65a228fSRobert Mustacchi 		ret &= memstream_check_seek(fw, seeks[i].newpos, SEEK_CUR);
1466*f65a228fSRobert Mustacchi 	}
1467*f65a228fSRobert Mustacchi 
1468*f65a228fSRobert Mustacchi 	(void) fclose(f);
1469*f65a228fSRobert Mustacchi 	(void) fclose(fw);
1470*f65a228fSRobert Mustacchi 	free(c);
1471*f65a228fSRobert Mustacchi 	free(w);
1472*f65a228fSRobert Mustacchi 	return (ret);
1473*f65a228fSRobert Mustacchi }
1474*f65a228fSRobert Mustacchi 
1475*f65a228fSRobert Mustacchi static boolean_t
open_memstream_append_nul(void)1476*f65a228fSRobert Mustacchi open_memstream_append_nul(void)
1477*f65a228fSRobert Mustacchi {
1478*f65a228fSRobert Mustacchi 	char *c;
1479*f65a228fSRobert Mustacchi 	size_t s;
1480*f65a228fSRobert Mustacchi 	FILE *f;
1481*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1482*f65a228fSRobert Mustacchi 
1483*f65a228fSRobert Mustacchi 	if ((f = open_memstream(&c, &s)) == NULL) {
1484*f65a228fSRobert Mustacchi 		warn("failed to call open_memstream()");
1485*f65a228fSRobert Mustacchi 		return (B_FALSE);
1486*f65a228fSRobert Mustacchi 	}
1487*f65a228fSRobert Mustacchi 
1488*f65a228fSRobert Mustacchi 	if (fputc('a', f) != 'a') {
1489*f65a228fSRobert Mustacchi 		warn("failed to write 'a' to stream");
1490*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1491*f65a228fSRobert Mustacchi 	}
1492*f65a228fSRobert Mustacchi 
1493*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1494*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1495*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1496*f65a228fSRobert Mustacchi 	}
1497*f65a228fSRobert Mustacchi 
1498*f65a228fSRobert Mustacchi 	if (c[s] != '\0') {
1499*f65a228fSRobert Mustacchi 		warnx("missing nul character, found %x", c[s]);
1500*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1501*f65a228fSRobert Mustacchi 	}
1502*f65a228fSRobert Mustacchi 
1503*f65a228fSRobert Mustacchi 	if (fseek(f, arc4random_uniform(2 * BUFSIZ), SEEK_SET) != 0) {
1504*f65a228fSRobert Mustacchi 		warn("failed to seek");
1505*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1506*f65a228fSRobert Mustacchi 	}
1507*f65a228fSRobert Mustacchi 
1508*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1509*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1510*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1511*f65a228fSRobert Mustacchi 	}
1512*f65a228fSRobert Mustacchi 
1513*f65a228fSRobert Mustacchi 	if (c[s] != '\0') {
1514*f65a228fSRobert Mustacchi 		warnx("missing nul character, found %x", c[s]);
1515*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1516*f65a228fSRobert Mustacchi 	}
1517*f65a228fSRobert Mustacchi 
1518*f65a228fSRobert Mustacchi 	(void) fclose(f);
1519*f65a228fSRobert Mustacchi 	free(c);
1520*f65a228fSRobert Mustacchi 	return (ret);
1521*f65a228fSRobert Mustacchi }
1522*f65a228fSRobert Mustacchi 
1523*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_append_nul(void)1524*f65a228fSRobert Mustacchi open_wmemstream_append_nul(void)
1525*f65a228fSRobert Mustacchi {
1526*f65a228fSRobert Mustacchi 	wchar_t *c;
1527*f65a228fSRobert Mustacchi 	size_t s;
1528*f65a228fSRobert Mustacchi 	FILE *f;
1529*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1530*f65a228fSRobert Mustacchi 
1531*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1532*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1533*f65a228fSRobert Mustacchi 		return (B_FALSE);
1534*f65a228fSRobert Mustacchi 	}
1535*f65a228fSRobert Mustacchi 
1536*f65a228fSRobert Mustacchi 	if (fputwc('a', f) != 'a') {
1537*f65a228fSRobert Mustacchi 		warn("failed to write 'a' to stream");
1538*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1539*f65a228fSRobert Mustacchi 	}
1540*f65a228fSRobert Mustacchi 
1541*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1542*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1543*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1544*f65a228fSRobert Mustacchi 	}
1545*f65a228fSRobert Mustacchi 
1546*f65a228fSRobert Mustacchi 	if (c[s] != L'\0') {
1547*f65a228fSRobert Mustacchi 		warnx("missing nul character, found %x", c[s]);
1548*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1549*f65a228fSRobert Mustacchi 	}
1550*f65a228fSRobert Mustacchi 
1551*f65a228fSRobert Mustacchi 	if (fseek(f, arc4random_uniform(2 * BUFSIZ), SEEK_SET) != 0) {
1552*f65a228fSRobert Mustacchi 		warn("failed to seek");
1553*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1554*f65a228fSRobert Mustacchi 	}
1555*f65a228fSRobert Mustacchi 
1556*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1557*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1558*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1559*f65a228fSRobert Mustacchi 	}
1560*f65a228fSRobert Mustacchi 
1561*f65a228fSRobert Mustacchi 	if (c[s] != L'\0') {
1562*f65a228fSRobert Mustacchi 		warnx("missing nul character, found %x", c[s]);
1563*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1564*f65a228fSRobert Mustacchi 	}
1565*f65a228fSRobert Mustacchi 
1566*f65a228fSRobert Mustacchi 	(void) fclose(f);
1567*f65a228fSRobert Mustacchi 	free(c);
1568*f65a228fSRobert Mustacchi 	return (ret);
1569*f65a228fSRobert Mustacchi }
1570*f65a228fSRobert Mustacchi 
1571*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_embed_nuls(void)1572*f65a228fSRobert Mustacchi open_wmemstream_embed_nuls(void)
1573*f65a228fSRobert Mustacchi {
1574*f65a228fSRobert Mustacchi 	const char str[] = { 'H', 'e', 'l', 'l', 'o', '\0', 'w',
1575*f65a228fSRobert Mustacchi 	    'o', 'r', 'd' };
1576*f65a228fSRobert Mustacchi 	const wchar_t wstr[] = { L'H', L'e', L'l', L'l', L'o', L'\0', L'w',
1577*f65a228fSRobert Mustacchi 	    L'o', L'r', L'd' };
1578*f65a228fSRobert Mustacchi 	wchar_t *c;
1579*f65a228fSRobert Mustacchi 	size_t s;
1580*f65a228fSRobert Mustacchi 	FILE *f;
1581*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1582*f65a228fSRobert Mustacchi 
1583*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1584*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1585*f65a228fSRobert Mustacchi 		return (B_FALSE);
1586*f65a228fSRobert Mustacchi 	}
1587*f65a228fSRobert Mustacchi 
1588*f65a228fSRobert Mustacchi 	if (fwrite(str, sizeof (char), ARRAY_SIZE(str), f) == 0) {
1589*f65a228fSRobert Mustacchi 		warn("failed to write data buffer");
1590*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1591*f65a228fSRobert Mustacchi 	}
1592*f65a228fSRobert Mustacchi 
1593*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1594*f65a228fSRobert Mustacchi 		warn("failed to flush data buffer");
1595*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1596*f65a228fSRobert Mustacchi 	}
1597*f65a228fSRobert Mustacchi 
1598*f65a228fSRobert Mustacchi 	if (ARRAY_SIZE(wstr) != s) {
1599*f65a228fSRobert Mustacchi 		warnx("size mismatch, wrote %zu chars, found %zu chars",
1600*f65a228fSRobert Mustacchi 		    ARRAY_SIZE(wstr), s);
1601*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1602*f65a228fSRobert Mustacchi 	}
1603*f65a228fSRobert Mustacchi 
1604*f65a228fSRobert Mustacchi 	if (bcmp(wstr, c, sizeof (wstr)) != 0) {
1605*f65a228fSRobert Mustacchi 		warnx("data not written in expected format");
1606*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1607*f65a228fSRobert Mustacchi 	}
1608*f65a228fSRobert Mustacchi 
1609*f65a228fSRobert Mustacchi 	(void) fclose(f);
1610*f65a228fSRobert Mustacchi 	free(c);
1611*f65a228fSRobert Mustacchi 	return (ret);
1612*f65a228fSRobert Mustacchi }
1613*f65a228fSRobert Mustacchi 
1614*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_wide_write(void)1615*f65a228fSRobert Mustacchi open_wmemstream_wide_write(void)
1616*f65a228fSRobert Mustacchi {
1617*f65a228fSRobert Mustacchi 	size_t slen = wcslen(wstream_str);
1618*f65a228fSRobert Mustacchi 	wchar_t *c;
1619*f65a228fSRobert Mustacchi 	size_t s;
1620*f65a228fSRobert Mustacchi 	FILE *f;
1621*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1622*f65a228fSRobert Mustacchi 
1623*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1624*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1625*f65a228fSRobert Mustacchi 		return (B_FALSE);
1626*f65a228fSRobert Mustacchi 	}
1627*f65a228fSRobert Mustacchi 
1628*f65a228fSRobert Mustacchi 	if (fputws(wstream_str, f) == -1) {
1629*f65a228fSRobert Mustacchi 		warn("failed to write string");
1630*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1631*f65a228fSRobert Mustacchi 	}
1632*f65a228fSRobert Mustacchi 
1633*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1634*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1635*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1636*f65a228fSRobert Mustacchi 	}
1637*f65a228fSRobert Mustacchi 
1638*f65a228fSRobert Mustacchi 	if (s != slen) {
1639*f65a228fSRobert Mustacchi 		warnx("size mismatch, expected %zu chars, but found %zu",
1640*f65a228fSRobert Mustacchi 		    slen, s);
1641*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1642*f65a228fSRobert Mustacchi 	}
1643*f65a228fSRobert Mustacchi 
1644*f65a228fSRobert Mustacchi 	if (wcscmp(wstream_str, c) != 0) {
1645*f65a228fSRobert Mustacchi 		warnx("basic write doesn't match!");
1646*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1647*f65a228fSRobert Mustacchi 	}
1648*f65a228fSRobert Mustacchi 
1649*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, slen, SEEK_CUR);
1650*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, slen, SEEK_END);
1651*f65a228fSRobert Mustacchi 
1652*f65a228fSRobert Mustacchi 	(void) fclose(f);
1653*f65a228fSRobert Mustacchi 	free(c);
1654*f65a228fSRobert Mustacchi 	return (ret);
1655*f65a228fSRobert Mustacchi }
1656*f65a228fSRobert Mustacchi 
1657*f65a228fSRobert Mustacchi /*
1658*f65a228fSRobert Mustacchi  * Make sure that if we seek somewhere and flush that it doesn't cause us to
1659*f65a228fSRobert Mustacchi  * grow.
1660*f65a228fSRobert Mustacchi  */
1661*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_seek_grow(void)1662*f65a228fSRobert Mustacchi open_wmemstream_seek_grow(void)
1663*f65a228fSRobert Mustacchi {
1664*f65a228fSRobert Mustacchi 	size_t slen = wcslen(wstream_str);
1665*f65a228fSRobert Mustacchi 	wchar_t *c;
1666*f65a228fSRobert Mustacchi 	size_t s;
1667*f65a228fSRobert Mustacchi 	FILE *f;
1668*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1669*f65a228fSRobert Mustacchi 
1670*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1671*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1672*f65a228fSRobert Mustacchi 		return (B_FALSE);
1673*f65a228fSRobert Mustacchi 	}
1674*f65a228fSRobert Mustacchi 
1675*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1676*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1677*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1678*f65a228fSRobert Mustacchi 	}
1679*f65a228fSRobert Mustacchi 
1680*f65a228fSRobert Mustacchi 	if (s != 0) {
1681*f65a228fSRobert Mustacchi 		warn("bad initial size");
1682*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1683*f65a228fSRobert Mustacchi 	}
1684*f65a228fSRobert Mustacchi 
1685*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, 0, SEEK_CUR);
1686*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, 0, SEEK_END);
1687*f65a228fSRobert Mustacchi 	if (fseek(f, 2048, SEEK_SET) != 0) {
1688*f65a228fSRobert Mustacchi 		warn("failed to seek");
1689*f65a228fSRobert Mustacchi 	}
1690*f65a228fSRobert Mustacchi 
1691*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, 2048, SEEK_CUR);
1692*f65a228fSRobert Mustacchi 
1693*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1694*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1695*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1696*f65a228fSRobert Mustacchi 	}
1697*f65a228fSRobert Mustacchi 
1698*f65a228fSRobert Mustacchi 	if (s != 0) {
1699*f65a228fSRobert Mustacchi 		warnx("bad size after seek");
1700*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1701*f65a228fSRobert Mustacchi 	}
1702*f65a228fSRobert Mustacchi 
1703*f65a228fSRobert Mustacchi 	if (fputws(wstream_str, f) == -1) {
1704*f65a228fSRobert Mustacchi 		warn("failed to write string");
1705*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1706*f65a228fSRobert Mustacchi 	}
1707*f65a228fSRobert Mustacchi 
1708*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1709*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1710*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1711*f65a228fSRobert Mustacchi 	}
1712*f65a228fSRobert Mustacchi 
1713*f65a228fSRobert Mustacchi 	if (s != slen + 2048) {
1714*f65a228fSRobert Mustacchi 		warnx("size is off after seek and write, found %zu", s);
1715*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1716*f65a228fSRobert Mustacchi 	}
1717*f65a228fSRobert Mustacchi 
1718*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, s, SEEK_CUR);
1719*f65a228fSRobert Mustacchi 	ret &= memstream_check_seek(f, s, SEEK_END);
1720*f65a228fSRobert Mustacchi 
1721*f65a228fSRobert Mustacchi 	(void) fclose(f);
1722*f65a228fSRobert Mustacchi 	free(c);
1723*f65a228fSRobert Mustacchi 	return (ret);
1724*f65a228fSRobert Mustacchi }
1725*f65a228fSRobert Mustacchi 
1726*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_byte_writes(void)1727*f65a228fSRobert Mustacchi open_wmemstream_byte_writes(void)
1728*f65a228fSRobert Mustacchi {
1729*f65a228fSRobert Mustacchi 	wchar_t *c;
1730*f65a228fSRobert Mustacchi 	size_t s, len, i;
1731*f65a228fSRobert Mustacchi 	FILE *f;
1732*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1733*f65a228fSRobert Mustacchi 
1734*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1735*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1736*f65a228fSRobert Mustacchi 		return (B_FALSE);
1737*f65a228fSRobert Mustacchi 	}
1738*f65a228fSRobert Mustacchi 
1739*f65a228fSRobert Mustacchi 	/*
1740*f65a228fSRobert Mustacchi 	 * Use non-buffered mode so that way we can make sure to detect mbs
1741*f65a228fSRobert Mustacchi 	 * state errors right away.
1742*f65a228fSRobert Mustacchi 	 */
1743*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
1744*f65a228fSRobert Mustacchi 		warnx("failed to set to non-buffered mode");
1745*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1746*f65a228fSRobert Mustacchi 	}
1747*f65a228fSRobert Mustacchi 
1748*f65a228fSRobert Mustacchi 	len = wcslen(wstream_str);
1749*f65a228fSRobert Mustacchi 	for (i = 0; i < len; i++) {
1750*f65a228fSRobert Mustacchi 		char buf[MB_CUR_MAX + 1];
1751*f65a228fSRobert Mustacchi 		int mblen, curmb;
1752*f65a228fSRobert Mustacchi 
1753*f65a228fSRobert Mustacchi 		mblen = wctomb(buf, wstream_str[i]);
1754*f65a228fSRobert Mustacchi 
1755*f65a228fSRobert Mustacchi 		if (mblen == -1) {
1756*f65a228fSRobert Mustacchi 			warn("failed to convert wc %zu", i);
1757*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1758*f65a228fSRobert Mustacchi 			continue;
1759*f65a228fSRobert Mustacchi 		}
1760*f65a228fSRobert Mustacchi 		for (curmb = 0; curmb < mblen; curmb++) {
1761*f65a228fSRobert Mustacchi 			if (fputc(buf[curmb], f) == EOF) {
1762*f65a228fSRobert Mustacchi 				warn("failed to write byte %d of wc %zu",
1763*f65a228fSRobert Mustacchi 				    curmb, i);
1764*f65a228fSRobert Mustacchi 				ret = B_FALSE;
1765*f65a228fSRobert Mustacchi 			}
1766*f65a228fSRobert Mustacchi 		}
1767*f65a228fSRobert Mustacchi 	}
1768*f65a228fSRobert Mustacchi 
1769*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1770*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1771*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1772*f65a228fSRobert Mustacchi 	}
1773*f65a228fSRobert Mustacchi 
1774*f65a228fSRobert Mustacchi 	if (s != len) {
1775*f65a228fSRobert Mustacchi 		warnx("found wrong number of wide characters, expected %zu, "
1776*f65a228fSRobert Mustacchi 		    "found %zu", len + 1, s);
1777*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1778*f65a228fSRobert Mustacchi 	}
1779*f65a228fSRobert Mustacchi 
1780*f65a228fSRobert Mustacchi 	if (wcscmp(c, wstream_str) != 0) {
1781*f65a228fSRobert Mustacchi 		warnx("the wide character strings don't compare equally");
1782*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1783*f65a228fSRobert Mustacchi 	}
1784*f65a228fSRobert Mustacchi 
1785*f65a228fSRobert Mustacchi 	(void) fclose(f);
1786*f65a228fSRobert Mustacchi 	free(c);
1787*f65a228fSRobert Mustacchi 	return (ret);
1788*f65a228fSRobert Mustacchi }
1789*f65a228fSRobert Mustacchi 
1790*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_bad_seq(void)1791*f65a228fSRobert Mustacchi open_wmemstream_bad_seq(void)
1792*f65a228fSRobert Mustacchi {
1793*f65a228fSRobert Mustacchi 	wchar_t *c, test = wstr_const[0];
1794*f65a228fSRobert Mustacchi 	size_t s;
1795*f65a228fSRobert Mustacchi 	FILE *f;
1796*f65a228fSRobert Mustacchi 	char buf[MB_CUR_MAX + 1];
1797*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1798*f65a228fSRobert Mustacchi 
1799*f65a228fSRobert Mustacchi 	if (wctomb(buf, test) == -1) {
1800*f65a228fSRobert Mustacchi 		warn("failed to convert 光 to multi-byte sequence");
1801*f65a228fSRobert Mustacchi 		return (B_FALSE);
1802*f65a228fSRobert Mustacchi 	}
1803*f65a228fSRobert Mustacchi 
1804*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1805*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1806*f65a228fSRobert Mustacchi 		return (B_FALSE);
1807*f65a228fSRobert Mustacchi 	}
1808*f65a228fSRobert Mustacchi 
1809*f65a228fSRobert Mustacchi 	/*
1810*f65a228fSRobert Mustacchi 	 * Make sure to use a non-buffered mode so that way writes immediately
1811*f65a228fSRobert Mustacchi 	 * get sent to the underlying stream.
1812*f65a228fSRobert Mustacchi 	 */
1813*f65a228fSRobert Mustacchi 	if (setvbuf(f, NULL, _IONBF, 0) != 0) {
1814*f65a228fSRobert Mustacchi 		warnx("failed to set to non-buffered mode");
1815*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1816*f65a228fSRobert Mustacchi 	}
1817*f65a228fSRobert Mustacchi 
1818*f65a228fSRobert Mustacchi 	if (fputc(buf[0], f) == EOF) {
1819*f65a228fSRobert Mustacchi 		warn("failed to write 0x%x to buffer", buf[0]);
1820*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1821*f65a228fSRobert Mustacchi 	}
1822*f65a228fSRobert Mustacchi 
1823*f65a228fSRobert Mustacchi 	if (fputc(buf[0], f) != EOF) {
1824*f65a228fSRobert Mustacchi 		warnx("successfully wrote 0x%x to buffer, but should have "
1825*f65a228fSRobert Mustacchi 		    "failed", buf[0]);
1826*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1827*f65a228fSRobert Mustacchi 	}
1828*f65a228fSRobert Mustacchi 
1829*f65a228fSRobert Mustacchi 	if (errno != EIO) {
1830*f65a228fSRobert Mustacchi 		warnx("found wrong errno, expected EIO, but found 0x%x", errno);
1831*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1832*f65a228fSRobert Mustacchi 	}
1833*f65a228fSRobert Mustacchi 
1834*f65a228fSRobert Mustacchi 	(void) fclose(f);
1835*f65a228fSRobert Mustacchi 	free(c);
1836*f65a228fSRobert Mustacchi 	return (ret);
1837*f65a228fSRobert Mustacchi }
1838*f65a228fSRobert Mustacchi 
1839*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_bad_seq_fflush(void)1840*f65a228fSRobert Mustacchi open_wmemstream_bad_seq_fflush(void)
1841*f65a228fSRobert Mustacchi {
1842*f65a228fSRobert Mustacchi 	wchar_t *c, test = wstr_const[0];
1843*f65a228fSRobert Mustacchi 	size_t s;
1844*f65a228fSRobert Mustacchi 	FILE *f;
1845*f65a228fSRobert Mustacchi 	char buf[MB_CUR_MAX + 1];
1846*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1847*f65a228fSRobert Mustacchi 
1848*f65a228fSRobert Mustacchi 	if (wctomb(buf, test) == -1) {
1849*f65a228fSRobert Mustacchi 		warn("failed to convert 光 to multi-byte sequence");
1850*f65a228fSRobert Mustacchi 		return (B_FALSE);
1851*f65a228fSRobert Mustacchi 	}
1852*f65a228fSRobert Mustacchi 
1853*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1854*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1855*f65a228fSRobert Mustacchi 		return (B_FALSE);
1856*f65a228fSRobert Mustacchi 	}
1857*f65a228fSRobert Mustacchi 
1858*f65a228fSRobert Mustacchi 	if (fputc(buf[0], f) == EOF) {
1859*f65a228fSRobert Mustacchi 		warn("failed to write 0x%x to buffer", buf[0]);
1860*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1861*f65a228fSRobert Mustacchi 	}
1862*f65a228fSRobert Mustacchi 
1863*f65a228fSRobert Mustacchi 	if (fputc(buf[0], f) == EOF) {
1864*f65a228fSRobert Mustacchi 		warn("failed to write bad byte 0x%x to buffer", buf[0]);
1865*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1866*f65a228fSRobert Mustacchi 	}
1867*f65a228fSRobert Mustacchi 
1868*f65a228fSRobert Mustacchi 	if (fflush(f) == 0) {
1869*f65a228fSRobert Mustacchi 		warn("fflush succeeded, expected failure");
1870*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1871*f65a228fSRobert Mustacchi 	}
1872*f65a228fSRobert Mustacchi 
1873*f65a228fSRobert Mustacchi 	if (errno != EIO) {
1874*f65a228fSRobert Mustacchi 		warn("found wrong errno, expected EIO, but found 0x%x", errno);
1875*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1876*f65a228fSRobert Mustacchi 	}
1877*f65a228fSRobert Mustacchi 
1878*f65a228fSRobert Mustacchi 	(void) fclose(f);
1879*f65a228fSRobert Mustacchi 	free(c);
1880*f65a228fSRobert Mustacchi 	return (ret);
1881*f65a228fSRobert Mustacchi }
1882*f65a228fSRobert Mustacchi 
1883*f65a228fSRobert Mustacchi /*
1884*f65a228fSRobert Mustacchi  * When writing individual bytes out, we need to make sure that we don't
1885*f65a228fSRobert Mustacchi  * incorrectly count buffered data as offsets like we do for other byte oriented
1886*f65a228fSRobert Mustacchi  * consumers of the ftell family.
1887*f65a228fSRobert Mustacchi  */
1888*f65a228fSRobert Mustacchi static boolean_t
open_wmemstream_ftell(void)1889*f65a228fSRobert Mustacchi open_wmemstream_ftell(void)
1890*f65a228fSRobert Mustacchi {
1891*f65a228fSRobert Mustacchi 	wchar_t *c, test = wstr_const[0];
1892*f65a228fSRobert Mustacchi 	size_t s, i, wclen;
1893*f65a228fSRobert Mustacchi 	FILE *f;
1894*f65a228fSRobert Mustacchi 	char buf[MB_CUR_MAX + 1];
1895*f65a228fSRobert Mustacchi 	boolean_t ret = B_TRUE;
1896*f65a228fSRobert Mustacchi 	long loc;
1897*f65a228fSRobert Mustacchi 
1898*f65a228fSRobert Mustacchi 	if ((wclen = wctomb(buf, test)) == -1) {
1899*f65a228fSRobert Mustacchi 		warn("failed to convert 光 to multi-byte sequence");
1900*f65a228fSRobert Mustacchi 		return (B_FALSE);
1901*f65a228fSRobert Mustacchi 	}
1902*f65a228fSRobert Mustacchi 
1903*f65a228fSRobert Mustacchi 	if ((f = open_wmemstream(&c, &s)) == NULL) {
1904*f65a228fSRobert Mustacchi 		warn("failed to call open_wmemstream()");
1905*f65a228fSRobert Mustacchi 		return (B_FALSE);
1906*f65a228fSRobert Mustacchi 	}
1907*f65a228fSRobert Mustacchi 
1908*f65a228fSRobert Mustacchi 	if ((loc = ftell(f)) != 0) {
1909*f65a228fSRobert Mustacchi 		warnx("stream at bad loc after start, found %ld, expected 0",
1910*f65a228fSRobert Mustacchi 		    loc);
1911*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1912*f65a228fSRobert Mustacchi 	}
1913*f65a228fSRobert Mustacchi 
1914*f65a228fSRobert Mustacchi 	if (fputwc(test, f) == WEOF) {
1915*f65a228fSRobert Mustacchi 		warn("failed to write wide character to stream");
1916*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1917*f65a228fSRobert Mustacchi 	}
1918*f65a228fSRobert Mustacchi 
1919*f65a228fSRobert Mustacchi 	if ((loc = ftell(f)) != 1) {
1920*f65a228fSRobert Mustacchi 		warnx("stream at bad loc after writing a single wide char, "
1921*f65a228fSRobert Mustacchi 		    "found %ld, expected 1", loc);
1922*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1923*f65a228fSRobert Mustacchi 	}
1924*f65a228fSRobert Mustacchi 
1925*f65a228fSRobert Mustacchi 	for (i = 0; i < wclen - 1; i++) {
1926*f65a228fSRobert Mustacchi 		if (fputc(buf[i], f) == EOF) {
1927*f65a228fSRobert Mustacchi 			warn("failed to write mb char 0x%x", buf[i]);
1928*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1929*f65a228fSRobert Mustacchi 		}
1930*f65a228fSRobert Mustacchi 
1931*f65a228fSRobert Mustacchi 		if ((loc = ftell(f)) != 1) {
1932*f65a228fSRobert Mustacchi 			warnx("stream at bad loc after putting partial mb seq, "
1933*f65a228fSRobert Mustacchi 			    "found %ld, expected 1", loc);
1934*f65a228fSRobert Mustacchi 			ret = B_FALSE;
1935*f65a228fSRobert Mustacchi 		}
1936*f65a228fSRobert Mustacchi 	}
1937*f65a228fSRobert Mustacchi 
1938*f65a228fSRobert Mustacchi 	/*
1939*f65a228fSRobert Mustacchi 	 * Only after we advance the final char should it be two.
1940*f65a228fSRobert Mustacchi 	 */
1941*f65a228fSRobert Mustacchi 	if (fputc(buf[i], f) == EOF) {
1942*f65a228fSRobert Mustacchi 		warn("failed to write mb char 0x%x", buf[i]);
1943*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1944*f65a228fSRobert Mustacchi 	}
1945*f65a228fSRobert Mustacchi 
1946*f65a228fSRobert Mustacchi 	if ((loc = ftell(f)) != 2) {
1947*f65a228fSRobert Mustacchi 		warnx("stream at bad loc after writing a mb seq, "
1948*f65a228fSRobert Mustacchi 		    "found %ld, expected 2", loc);
1949*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1950*f65a228fSRobert Mustacchi 	}
1951*f65a228fSRobert Mustacchi 
1952*f65a228fSRobert Mustacchi 	if (fflush(f) != 0) {
1953*f65a228fSRobert Mustacchi 		warn("failed to flush stream");
1954*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1955*f65a228fSRobert Mustacchi 	}
1956*f65a228fSRobert Mustacchi 
1957*f65a228fSRobert Mustacchi 	if (s != 2) {
1958*f65a228fSRobert Mustacchi 		warnx("size of stream is wrong, found %zu, expected 2", s);
1959*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1960*f65a228fSRobert Mustacchi 	}
1961*f65a228fSRobert Mustacchi 
1962*f65a228fSRobert Mustacchi 	if (s != loc) {
1963*f65a228fSRobert Mustacchi 		warnx("size of buffer, %zu does not match pre-fflush "
1964*f65a228fSRobert Mustacchi 		    "ftell loc: %ld", s, loc);
1965*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1966*f65a228fSRobert Mustacchi 	}
1967*f65a228fSRobert Mustacchi 
1968*f65a228fSRobert Mustacchi 	loc = ftell(f);
1969*f65a228fSRobert Mustacchi 	if (s != loc) {
1970*f65a228fSRobert Mustacchi 		warnx("size of buffer, %zu does not match post-fflush "
1971*f65a228fSRobert Mustacchi 		    "ftell loc: %ld", s, loc);
1972*f65a228fSRobert Mustacchi 		ret = B_FALSE;
1973*f65a228fSRobert Mustacchi 	}
1974*f65a228fSRobert Mustacchi 
1975*f65a228fSRobert Mustacchi 	(void) fclose(f);
1976*f65a228fSRobert Mustacchi 	free(c);
1977*f65a228fSRobert Mustacchi 	return (ret);
1978*f65a228fSRobert Mustacchi }
1979*f65a228fSRobert Mustacchi 
1980*f65a228fSRobert Mustacchi 
1981*f65a228fSRobert Mustacchi typedef struct memstream_test {
1982*f65a228fSRobert Mustacchi 	memstream_test_f	mt_func;
1983*f65a228fSRobert Mustacchi 	const char		*mt_test;
1984*f65a228fSRobert Mustacchi } memstream_test_t;
1985*f65a228fSRobert Mustacchi 
1986*f65a228fSRobert Mustacchi static const memstream_test_t memstream_tests[] = {
1987*f65a228fSRobert Mustacchi 	{ fmemopen_badmode, "fmemopen: bad mode argument" },
1988*f65a228fSRobert Mustacchi 	{ fmemopen_zerobuf1, "fmemopen: bad buffer size, valid buf" },
1989*f65a228fSRobert Mustacchi 	{ fmemopen_zerobuf2, "fmemopen: bad buffer size, NULL buf" },
1990*f65a228fSRobert Mustacchi 	{ fmemopen_nullbuf1, "fmemopen: invalid NULL buf, mode: r" },
1991*f65a228fSRobert Mustacchi 	{ fmemopen_nullbuf2, "fmemopen: invalid NULL buf, mode: w" },
1992*f65a228fSRobert Mustacchi 	{ fmemopen_nullbuf3, "fmemopen: invalid NULL buf, mode: a" },
1993*f65a228fSRobert Mustacchi 	{ fmemopen_nullbuf4, "fmemopen: invalid NULL buf, mode: ax" },
1994*f65a228fSRobert Mustacchi 	{ fmemopen_sizemax, "fmemopen: bad open ask for SIZE_MAX bytes" },
1995*f65a228fSRobert Mustacchi 	{ fmemopen_cantalloc, "fmemopen: simulate malloc failure at open" },
1996*f65a228fSRobert Mustacchi 	{ open_memstream_badbuf, "open_memstream: bad buf" },
1997*f65a228fSRobert Mustacchi 	{ open_memstream_badsize, "open_memstream: bad size" },
1998*f65a228fSRobert Mustacchi 	{ open_memstream_allnull, "open_memstream: bad buf and size" },
1999*f65a228fSRobert Mustacchi 	{ open_memstream_cantalloc, "open_memstream: simulate malloc failure "
2000*f65a228fSRobert Mustacchi 	    "at " "open" },
2001*f65a228fSRobert Mustacchi 	{ open_wmemstream_badbuf, "open_wmemstream: bad buf" },
2002*f65a228fSRobert Mustacchi 	{ open_wmemstream_badsize, "open_wmemstream: bad size" },
2003*f65a228fSRobert Mustacchi 	{ open_wmemstream_allnull, "open_wmemstream: bad buf and size" },
2004*f65a228fSRobert Mustacchi 	{ open_wmemstream_cantalloc, "open_wmemstream: simulate malloc "
2005*f65a228fSRobert Mustacchi 	    "failure at open" },
2006*f65a228fSRobert Mustacchi 	{ fmemopen_fill_default, "fmemopen: write beyond end of buffer: putc "
2007*f65a228fSRobert Mustacchi 	    "(buf smaller than BUFSIZ)" },
2008*f65a228fSRobert Mustacchi 	{ fmemopen_fill_lbuf, "fmemopen: write beyond end of buffer: putc "
2009*f65a228fSRobert Mustacchi 	    "(line buffering)" },
2010*f65a228fSRobert Mustacchi 	{ fmemopen_fill_nobuf, "fmemopen: write beyond end of buffer: putc "
2011*f65a228fSRobert Mustacchi 	    "(no stdio buffering)" },
2012*f65a228fSRobert Mustacchi 	{ fmemopen_fwrite_default, "fmemopen: write beyond end of buffer: "
2013*f65a228fSRobert Mustacchi 	    "fwrite (buf smaller than BUFSIZ)" },
2014*f65a228fSRobert Mustacchi 	{ fmemopen_fwrite_lbuf, "fmemopen: write beyond end of buffer: fwrite "
2015*f65a228fSRobert Mustacchi 	    "(line buffering)" },
2016*f65a228fSRobert Mustacchi 	{ fmemopen_fwrite_nobuf, "fmemopen: write beyond end of buffer: fwrite "
2017*f65a228fSRobert Mustacchi 	    "(no stdio buffering)" },
2018*f65a228fSRobert Mustacchi 	{ fmemopen_alt_fwrite_default, "fmemopen: write beyond end of buffer: "
2019*f65a228fSRobert Mustacchi 	    "fwrite 2 (buf smaller than BUFSIZ)" },
2020*f65a228fSRobert Mustacchi 	{ fmemopen_alt_fwrite_lbuf, "fmemopen: write beyond end of buffer: "
2021*f65a228fSRobert Mustacchi 	    "fwrite 2 (line buffering)" },
2022*f65a228fSRobert Mustacchi 	{ fmemopen_alt_fwrite_nobuf, "fmemopen: write beyond end of buffer: "
2023*f65a228fSRobert Mustacchi 	    "fwrite 2 (no stdio buffering)" },
2024*f65a228fSRobert Mustacchi 	{ fmemopen_fputs_default, "fmemopen: write beyond end of buffer: fputs "
2025*f65a228fSRobert Mustacchi 	    "(buf smaller than BUFSIZ)" },
2026*f65a228fSRobert Mustacchi 	{ fmemopen_fputs_lbuf, "fmemopen: write beyond end of buffer: fputs "
2027*f65a228fSRobert Mustacchi 	    "(line buffering)" },
2028*f65a228fSRobert Mustacchi 	{ fmemopen_fputs_nobuf, "fmemopen: write beyond end of buffer: fputs "
2029*f65a228fSRobert Mustacchi 	    "(no stdio buffering)" },
2030*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_r, "fmemopen: default position and log. size, "
2031*f65a228fSRobert Mustacchi 	    "mode: r"},
2032*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_rp, "fmemopen: default position and log. size, "
2033*f65a228fSRobert Mustacchi 	    "mode: r+"},
2034*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_w, "fmemopen: default position and log. size, "
2035*f65a228fSRobert Mustacchi 	    "mode: w"},
2036*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_wp, "fmemopen: default position and log. size, "
2037*f65a228fSRobert Mustacchi 	    "mode: w+"},
2038*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_a, "fmemopen: default position and log. size, "
2039*f65a228fSRobert Mustacchi 	    "mode: a"},
2040*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_ap, "fmemopen: default position and log. size, "
2041*f65a228fSRobert Mustacchi 	    "mode: a+"},
2042*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_a_nbyte, "fmemopen: default position and log. size, "
2043*f65a228fSRobert Mustacchi 	    "mode: a, nul byte"},
2044*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_ap_nbyte, "fmemopen: default position and log. "
2045*f65a228fSRobert Mustacchi 	    "size, mode: a+, nul byte"},
2046*f65a228fSRobert Mustacchi 	{ fmemopen_defseek_ap_null, "fmemopen: default position and log. size, "
2047*f65a228fSRobert Mustacchi 	    "mode: a+, NULL buf"},
2048*f65a228fSRobert Mustacchi 	{ fmemopen_read_eof_fgetc, "fmemopen: read until EOF with fgetc" },
2049*f65a228fSRobert Mustacchi 	{ fmemopen_read_eof_fgets, "fmemopen: read until EOF with fgets" },
2050*f65a228fSRobert Mustacchi 	{ fmemopen_read_eof_fread, "fmemopen: read until EOF with fread" },
2051*f65a228fSRobert Mustacchi 	{ fmemopen_read_eof_fread2, "fmemopen: read until EOF with fread 2" },
2052*f65a228fSRobert Mustacchi 	{ fmemopen_bad_seeks, "fmemopen: invalid seeks" },
2053*f65a228fSRobert Mustacchi 	{ fmemopen_open_trunc, "fmemopen: w+ mode truncates buffer" },
2054*f65a228fSRobert Mustacchi 	{ fmemopen_write_nul, "fmemopen: NULs properly inserted (w)" },
2055*f65a228fSRobert Mustacchi 	{ fmemopen_append_nul, "fmemopen: NULs properly inserted (a)" },
2056*f65a228fSRobert Mustacchi 	{ fmemopen_read_nul, "fmemopen: read NUL character normally" },
2057*f65a228fSRobert Mustacchi 	{ open_memstream_def_seek, "open_memstream: default position and "
2058*f65a228fSRobert Mustacchi 	    "logical size" },
2059*f65a228fSRobert Mustacchi 	{ open_wmemstream_def_seek, "wopen_memstream: default position and "
2060*f65a228fSRobert Mustacchi 	    "logical size" },
2061*f65a228fSRobert Mustacchi 	{ open_memstream_no_read, "open_memstream: read doesn't work" },
2062*f65a228fSRobert Mustacchi 	{ open_wmemstream_no_read, "open_wmemstream: read doesn't work" },
2063*f65a228fSRobert Mustacchi 	{ open_memstream_bad_flush, "open_memstream: flush failure due to "
2064*f65a228fSRobert Mustacchi 	    "induced memory failure" },
2065*f65a228fSRobert Mustacchi 	{ open_wmemstream_bad_flush, "open_wmemstream: flush failure due to "
2066*f65a228fSRobert Mustacchi 	    "induced memory failure" },
2067*f65a228fSRobert Mustacchi 	{ memstream_bad_seek, "open_[w]memstream: bad seeks" },
2068*f65a228fSRobert Mustacchi 	{ open_memstream_append_nul, "open_memstream: appends NULs" },
2069*f65a228fSRobert Mustacchi 	{ open_wmemstream_append_nul, "open_wmemstream: appends NULs" },
2070*f65a228fSRobert Mustacchi 	{ open_wmemstream_embed_nuls, "open_wmemstream: handles embedded "
2071*f65a228fSRobert Mustacchi 	    "NULs" },
2072*f65a228fSRobert Mustacchi 	{ open_wmemstream_wide_write, "open_wmemstream: write wide chars" },
2073*f65a228fSRobert Mustacchi 	{ open_wmemstream_seek_grow, "open_wmemstream: seeking doesn't grow" },
2074*f65a228fSRobert Mustacchi 	{ open_wmemstream_byte_writes, "open_wmemstream: Write mb sequences" },
2075*f65a228fSRobert Mustacchi 	{ open_wmemstream_bad_seq, "open_wmemstream: detect bad utf-8 "
2076*f65a228fSRobert Mustacchi 	    "sequence" },
2077*f65a228fSRobert Mustacchi 	{ open_wmemstream_bad_seq_fflush, "open_wmemstream: detect bad utf-8 "
2078*f65a228fSRobert Mustacchi 	    "sequence 2 (fflush)" },
2079*f65a228fSRobert Mustacchi 	{ open_wmemstream_ftell, "open_wmemstream: ftell buffering behavior" }
2080*f65a228fSRobert Mustacchi };
2081*f65a228fSRobert Mustacchi 
2082*f65a228fSRobert Mustacchi int
main(void)2083*f65a228fSRobert Mustacchi main(void)
2084*f65a228fSRobert Mustacchi {
2085*f65a228fSRobert Mustacchi 	uint_t i;
2086*f65a228fSRobert Mustacchi 	uint_t passes = 0;
2087*f65a228fSRobert Mustacchi 	uint_t ntests = ARRAY_SIZE(memstream_tests);
2088*f65a228fSRobert Mustacchi 
2089*f65a228fSRobert Mustacchi 	/*
2090*f65a228fSRobert Mustacchi 	 * Set a UTF-8 locale to make sure to exercise open_wmemstream()'s
2091*f65a228fSRobert Mustacchi 	 * mbstate logic in a more interesting way than ASCII.
2092*f65a228fSRobert Mustacchi 	 */
2093*f65a228fSRobert Mustacchi 	(void) setlocale(LC_ALL, "en_US.UTF-8");
2094*f65a228fSRobert Mustacchi 	for (i = 0; i < ntests; i++) {
2095*f65a228fSRobert Mustacchi 		boolean_t r;
2096*f65a228fSRobert Mustacchi 
2097*f65a228fSRobert Mustacchi 		r = memstream_tests[i].mt_func();
2098*f65a228fSRobert Mustacchi 		(void) fprintf(stderr, "TEST %s: %s\n", r ? "PASSED" : "FAILED",
2099*f65a228fSRobert Mustacchi 		    memstream_tests[i].mt_test);
2100*f65a228fSRobert Mustacchi 		if (r) {
2101*f65a228fSRobert Mustacchi 			passes++;
2102*f65a228fSRobert Mustacchi 		}
2103*f65a228fSRobert Mustacchi 	}
2104*f65a228fSRobert Mustacchi 
2105*f65a228fSRobert Mustacchi 	(void) printf("%d/%d test%s passed\n", passes, ntests,
2106*f65a228fSRobert Mustacchi 	    passes > 1 ? "s" : "");
2107*f65a228fSRobert Mustacchi 	return (passes == ntests ? EXIT_SUCCESS : EXIT_FAILURE);
2108*f65a228fSRobert Mustacchi }
2109