1 /* $OpenBSD: open_memstreamtest.c,v 1.6 2019/05/13 02:54:54 bluhm Exp $ */
2
3 /*
4 * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <err.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #define OFFSET 16384
26
27 const char start[] = "start";
28 const char hello[] = "hello";
29
30 int
main(void)31 main(void)
32 {
33 FILE *fp;
34 char *buf = (char *)0xff;
35 size_t size = 0;
36 off_t off;
37 int i, failures = 0;
38
39 if ((fp = open_memstream(&buf, &size)) == NULL) {
40 warn("open_memstream failed");
41 return (1);
42 }
43
44 off = ftello(fp);
45 if (off != 0) {
46 warnx("ftello failed. (1)");
47 failures++;
48 }
49
50 if (fflush(fp) != 0) {
51 warnx("fflush failed. (2)");
52 failures++;
53 }
54
55 if (size != 0) {
56 warnx("string should be empty. (3)");
57 failures++;
58 }
59
60 if (buf == (char *)0xff) {
61 warnx("buf not updated. (4)");
62 failures++;
63 }
64
65 if (fseek(fp, OFFSET, SEEK_SET) != 0) {
66 warnx("failed to fseek. (5)");
67 failures++;
68 }
69
70 if (fprintf(fp, hello) == EOF) {
71 warnx("fprintf failed. (6)");
72 failures++;
73 }
74
75 if (fflush(fp) == EOF) {
76 warnx("fflush failed. (7)");
77 failures++;
78 }
79
80 if (size != OFFSET + sizeof(hello)-1) {
81 warnx("failed, size %zu should be %zu. (8)",
82 size, OFFSET + sizeof(hello)-1);
83 failures++;
84 }
85
86 if (fseek(fp, 0, SEEK_SET) != 0) {
87 warnx("failed to fseek. (9)");
88 failures++;
89 }
90
91 if (fprintf(fp, start) == EOF) {
92 warnx("fprintf failed. (10)");
93 failures++;
94 }
95
96 if (fflush(fp) == EOF) {
97 warnx("fflush failed. (11)");
98 failures++;
99 }
100
101 if (size != sizeof(start)-1) {
102 warnx("failed, size %zu should be %zu. (12)",
103 size, sizeof(start)-1);
104 failures++;
105 }
106
107 /* Needed for sparse files */
108 if (strncmp(buf, start, sizeof(start)-1) != 0) {
109 warnx("failed, buffer didn't start with '%s'. (13)", start);
110 failures++;
111 }
112 for (i = sizeof(start)-1; i < OFFSET; i++)
113 if (buf[i] != '\0') {
114 warnx("failed, buffer non zero (offset %d). (14)", i);
115 failures++;
116 break;
117 }
118
119 if (memcmp(buf + OFFSET, hello, sizeof(hello)-1) != 0) {
120 warnx("written string incorrect. (15)");
121 failures++;
122 }
123
124 /* verify that simply seeking past the end doesn't increase the size */
125 if (fseek(fp, 100, SEEK_END) != 0) {
126 warnx("failed to fseek. (16)");
127 failures++;
128 }
129
130 if (fflush(fp) == EOF) {
131 warnx("fflush failed. (17)");
132 failures++;
133 }
134
135 if (size != OFFSET + sizeof(hello)-1) {
136 warnx("failed, size %zu should be %zu. (18)",
137 size, OFFSET + sizeof(hello)-1);
138 failures++;
139 }
140
141 if (fseek(fp, -1, SEEK_END) != 0) {
142 warnx("failed to fseek. (19)");
143 failures++;
144 }
145
146 if (fseek(fp, 8, SEEK_SET) != 0) {
147 warnx("failed to fseek. (20)");
148 failures++;
149 }
150
151 if (ftell(fp) != 8) {
152 warnx("failed seek test. (21)");
153 failures++;
154 }
155
156 /* Try to seek backward */
157 if (fseek(fp, -1, SEEK_CUR) != 0) {
158 warnx("failed to fseek. (22)");
159 failures++;
160 }
161
162 if (ftell(fp) != 7) {
163 warnx("failed seeking backward. (23)");
164 failures++;
165 }
166
167 if (fseek(fp, 5, SEEK_CUR) != 0) {
168 warnx("failed to fseek. (24)");
169 failures++;
170 }
171
172 if (fclose(fp) == EOF) {
173 warnx("fclose failed. (25)");
174 failures++;
175 }
176
177 if (size != 12) {
178 warnx("failed, size %zu should be %u. (26)",
179 size, 12);
180 failures++;
181 }
182
183 free(buf);
184
185 return (failures);
186 }
187