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