]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - tools/regression/lib/libc/stdio/test-open_memstream.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / tools / regression / lib / libc / stdio / test-open_memstream.c
1 /*-
2  * Copyright (c) 2013 Advanced Computing Technologies LLC
3  * Written by: John H. Baldwin <jhb@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <err.h>
32 #include <errno.h>
33 #include <limits.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <wchar.h>
39
40 static char *buf;
41 static size_t len;
42
43 static void
44 assert_stream(const char *contents)
45 {
46         if (strlen(contents) != len)
47                 printf("bad length %zd for \"%s\"\n", len, contents);
48         else if (strncmp(buf, contents, strlen(contents)) != 0)
49                 printf("bad buffer \"%s\" for \"%s\"\n", buf, contents);
50 }
51
52 static void
53 open_group_test(void)
54 {
55         FILE *fp;
56         off_t eob;
57
58         fp = open_memstream(&buf, &len);
59         if (fp == NULL)
60                 err(1, "failed to open stream");
61
62         fprintf(fp, "hello my world");
63         fflush(fp);
64         assert_stream("hello my world");
65         eob = ftello(fp);
66         rewind(fp);
67         fprintf(fp, "good-bye");
68         fseeko(fp, eob, SEEK_SET);
69         fclose(fp);
70         assert_stream("good-bye world");
71         free(buf);
72 }
73
74 static void
75 simple_tests(void)
76 {
77         static const char zerobuf[] =
78             { 'f', 'o', 'o', 0, 0, 0, 0, 'b', 'a', 'r', 0 };
79         char c;
80         FILE *fp;
81
82         fp = open_memstream(&buf, NULL);
83         if (fp != NULL)
84                 errx(1, "did not fail to open stream");
85         else if (errno != EINVAL)
86                 err(1, "incorrect error for bad length pointer");
87         fp = open_memstream(NULL, &len);
88         if (fp != NULL)
89                 errx(1, "did not fail to open stream");
90         else if (errno != EINVAL)
91                 err(1, "incorrect error for bad buffer pointer");
92         fp = open_memstream(&buf, &len);
93         if (fp == NULL)
94                 err(1, "failed to open stream");
95         fflush(fp);
96         assert_stream("");
97         if (fwide(fp, 0) >= 0)
98                 printf("stream is not byte-oriented\n");
99
100         fprintf(fp, "fo");
101         fflush(fp);
102         assert_stream("fo");
103         fputc('o', fp);
104         fflush(fp);
105         assert_stream("foo");
106         rewind(fp);
107         fflush(fp);
108         assert_stream("");
109         fseek(fp, 0, SEEK_END);
110         fflush(fp);
111         assert_stream("foo");
112
113         /*
114          * Test seeking out past the current end.  Should zero-fill the
115          * intermediate area.
116          */
117         fseek(fp, 4, SEEK_END);
118         fprintf(fp, "bar");
119         fflush(fp);
120
121         /*
122          * Can't use assert_stream() here since this should contain
123          * embedded null characters.
124          */
125         if (len != 10)
126                 printf("bad length %zd for zero-fill test\n", len);
127         else if (memcmp(buf, zerobuf, sizeof(zerobuf)) != 0)
128                 printf("bad buffer for zero-fill test\n");
129
130         fseek(fp, 3, SEEK_SET);
131         fprintf(fp, " in ");
132         fflush(fp);
133         assert_stream("foo in ");
134         fseek(fp, 0, SEEK_END);
135         fflush(fp);
136         assert_stream("foo in bar");
137
138         rewind(fp);
139         if (fread(&c, sizeof(c), 1, fp) != 0)
140                 printf("fread did not fail\n");
141         else if (!ferror(fp))
142                 printf("error indicator not set after fread\n");
143         else
144                 clearerr(fp);
145
146         fseek(fp, 4, SEEK_SET);
147         fprintf(fp, "bar baz");
148         fclose(fp);
149         assert_stream("foo bar baz");
150         free(buf);
151 }
152
153 static void
154 seek_tests(void)
155 {
156         FILE *fp;
157
158         fp = open_memstream(&buf, &len);
159         if (fp == NULL)
160                 err(1, "failed to open stream");
161 #define SEEK_FAIL(offset, whence, error) do {                           \
162         errno = 0;                                                      \
163         if (fseeko(fp, (offset), (whence)) == 0)                        \
164                 printf("fseeko(%s, %s) did not fail, set pos to %jd\n", \
165                     __STRING(offset), __STRING(whence),                 \
166                     (intmax_t)ftello(fp));                              \
167         else if (errno != (error))                                      \
168                 printf("fseeko(%s, %s) failed with %d rather than %s\n",\
169                     __STRING(offset), __STRING(whence), errno,          \
170                     __STRING(error));                                   \
171 } while (0)
172
173 #define SEEK_OK(offset, whence, result) do {                            \
174         if (fseeko(fp, (offset), (whence)) != 0)                        \
175                 printf("fseeko(%s, %s) failed: %s\n",                   \
176                     __STRING(offset), __STRING(whence), strerror(errno)); \
177         else if (ftello(fp) != (result))                                \
178                 printf("fseeko(%s, %s) seeked to %jd rather than %s\n", \
179                     __STRING(offset), __STRING(whence),                 \
180                     (intmax_t)ftello(fp), __STRING(result));            \
181 } while (0)
182
183         SEEK_FAIL(-1, SEEK_SET, EINVAL);
184         SEEK_FAIL(-1, SEEK_CUR, EINVAL);
185         SEEK_FAIL(-1, SEEK_END, EINVAL);
186         fprintf(fp, "foo");
187         SEEK_OK(-1, SEEK_CUR, 2);
188         SEEK_OK(0, SEEK_SET, 0);
189         SEEK_OK(-1, SEEK_END, 2);
190         SEEK_OK(OFF_MAX - 1, SEEK_SET, OFF_MAX - 1);
191         SEEK_FAIL(2, SEEK_CUR, EOVERFLOW);
192         fclose(fp);
193 }
194
195 int
196 main(int ac, char **av)
197 {
198
199         open_group_test();
200         simple_tests();
201         seek_tests();
202         return (0);
203 }