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