1*0fca8acaSbluhm /* $OpenBSD: open_memstreamtest.c,v 1.6 2019/05/13 02:54:54 bluhm Exp $ */
2ee8af14aSmpi
323468c0eSmpi /*
423468c0eSmpi * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
523468c0eSmpi *
623468c0eSmpi * Permission to use, copy, modify, and distribute this software for any
723468c0eSmpi * purpose with or without fee is hereby granted, provided that the above
823468c0eSmpi * copyright notice and this permission notice appear in all copies.
923468c0eSmpi *
1023468c0eSmpi * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1123468c0eSmpi * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1223468c0eSmpi * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1323468c0eSmpi * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1423468c0eSmpi * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1523468c0eSmpi * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1623468c0eSmpi * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1723468c0eSmpi */
1823468c0eSmpi
1923468c0eSmpi #include <err.h>
2023468c0eSmpi #include <stdio.h>
2123468c0eSmpi #include <stdlib.h>
2223468c0eSmpi #include <string.h>
2323468c0eSmpi #include <unistd.h>
2423468c0eSmpi
2523468c0eSmpi #define OFFSET 16384
2623468c0eSmpi
27840b6301Sguenther const char start[] = "start";
28840b6301Sguenther const char hello[] = "hello";
29840b6301Sguenther
3023468c0eSmpi int
main(void)3123468c0eSmpi main(void)
3223468c0eSmpi {
3323468c0eSmpi FILE *fp;
3423468c0eSmpi char *buf = (char *)0xff;
3523468c0eSmpi size_t size = 0;
3623468c0eSmpi off_t off;
37840b6301Sguenther int i, failures = 0;
3823468c0eSmpi
3923468c0eSmpi if ((fp = open_memstream(&buf, &size)) == NULL) {
4023468c0eSmpi warn("open_memstream failed");
4123468c0eSmpi return (1);
4223468c0eSmpi }
4323468c0eSmpi
4423468c0eSmpi off = ftello(fp);
4523468c0eSmpi if (off != 0) {
4623468c0eSmpi warnx("ftello failed. (1)");
4723468c0eSmpi failures++;
4823468c0eSmpi }
4923468c0eSmpi
5023468c0eSmpi if (fflush(fp) != 0) {
5123468c0eSmpi warnx("fflush failed. (2)");
5223468c0eSmpi failures++;
5323468c0eSmpi }
5423468c0eSmpi
5523468c0eSmpi if (size != 0) {
5623468c0eSmpi warnx("string should be empty. (3)");
5723468c0eSmpi failures++;
5823468c0eSmpi }
5923468c0eSmpi
6023468c0eSmpi if (buf == (char *)0xff) {
6123468c0eSmpi warnx("buf not updated. (4)");
6223468c0eSmpi failures++;
6323468c0eSmpi }
6423468c0eSmpi
6523468c0eSmpi if (fseek(fp, OFFSET, SEEK_SET) != 0) {
6623468c0eSmpi warnx("failed to fseek. (5)");
6723468c0eSmpi failures++;
6823468c0eSmpi }
6923468c0eSmpi
70840b6301Sguenther if (fprintf(fp, hello) == EOF) {
7123468c0eSmpi warnx("fprintf failed. (6)");
7223468c0eSmpi failures++;
7323468c0eSmpi }
7423468c0eSmpi
75840b6301Sguenther if (fflush(fp) == EOF) {
76840b6301Sguenther warnx("fflush failed. (7)");
7723468c0eSmpi failures++;
7823468c0eSmpi }
7923468c0eSmpi
80840b6301Sguenther if (size != OFFSET + sizeof(hello)-1) {
812b1dab59Sguenther warnx("failed, size %zu should be %zu. (8)",
82840b6301Sguenther size, OFFSET + sizeof(hello)-1);
83840b6301Sguenther failures++;
84840b6301Sguenther }
85840b6301Sguenther
86840b6301Sguenther if (fseek(fp, 0, SEEK_SET) != 0) {
87840b6301Sguenther warnx("failed to fseek. (9)");
88840b6301Sguenther failures++;
89840b6301Sguenther }
90840b6301Sguenther
91840b6301Sguenther if (fprintf(fp, start) == EOF) {
92840b6301Sguenther warnx("fprintf failed. (10)");
93840b6301Sguenther failures++;
94840b6301Sguenther }
95840b6301Sguenther
96840b6301Sguenther if (fflush(fp) == EOF) {
97840b6301Sguenther warnx("fflush failed. (11)");
98840b6301Sguenther failures++;
99840b6301Sguenther }
100840b6301Sguenther
101840b6301Sguenther if (size != sizeof(start)-1) {
1022b1dab59Sguenther warnx("failed, size %zu should be %zu. (12)",
103840b6301Sguenther size, sizeof(start)-1);
10423468c0eSmpi failures++;
10523468c0eSmpi }
10623468c0eSmpi
10723468c0eSmpi /* Needed for sparse files */
108840b6301Sguenther if (strncmp(buf, start, sizeof(start)-1) != 0) {
109840b6301Sguenther warnx("failed, buffer didn't start with '%s'. (13)", start);
110840b6301Sguenther failures++;
111840b6301Sguenther }
112840b6301Sguenther for (i = sizeof(start)-1; i < OFFSET; i++)
113840b6301Sguenther if (buf[i] != '\0') {
114840b6301Sguenther warnx("failed, buffer non zero (offset %d). (14)", i);
11523468c0eSmpi failures++;
11623468c0eSmpi break;
11723468c0eSmpi }
11823468c0eSmpi
119840b6301Sguenther if (memcmp(buf + OFFSET, hello, sizeof(hello)-1) != 0) {
120840b6301Sguenther warnx("written string incorrect. (15)");
121840b6301Sguenther failures++;
122840b6301Sguenther }
123840b6301Sguenther
124840b6301Sguenther /* verify that simply seeking past the end doesn't increase the size */
125840b6301Sguenther if (fseek(fp, 100, SEEK_END) != 0) {
126840b6301Sguenther warnx("failed to fseek. (16)");
127840b6301Sguenther failures++;
128840b6301Sguenther }
129840b6301Sguenther
1302b1dab59Sguenther if (fflush(fp) == EOF) {
1312b1dab59Sguenther warnx("fflush failed. (17)");
132840b6301Sguenther failures++;
133840b6301Sguenther }
134840b6301Sguenther
135840b6301Sguenther if (size != OFFSET + sizeof(hello)-1) {
1362b1dab59Sguenther warnx("failed, size %zu should be %zu. (18)",
137840b6301Sguenther size, OFFSET + sizeof(hello)-1);
13823468c0eSmpi failures++;
13923468c0eSmpi }
14023468c0eSmpi
141*0fca8acaSbluhm if (fseek(fp, -1, SEEK_END) != 0) {
142ee8af14aSmpi warnx("failed to fseek. (19)");
143ee8af14aSmpi failures++;
144ee8af14aSmpi }
145ee8af14aSmpi
146*0fca8acaSbluhm if (fseek(fp, 8, SEEK_SET) != 0) {
147*0fca8acaSbluhm warnx("failed to fseek. (20)");
148*0fca8acaSbluhm failures++;
149*0fca8acaSbluhm }
150*0fca8acaSbluhm
151ee8af14aSmpi if (ftell(fp) != 8) {
152*0fca8acaSbluhm warnx("failed seek test. (21)");
153ee8af14aSmpi failures++;
154ee8af14aSmpi }
155ee8af14aSmpi
156ee8af14aSmpi /* Try to seek backward */
157ee8af14aSmpi if (fseek(fp, -1, SEEK_CUR) != 0) {
158*0fca8acaSbluhm warnx("failed to fseek. (22)");
159ee8af14aSmpi failures++;
160ee8af14aSmpi }
161ee8af14aSmpi
162ee8af14aSmpi if (ftell(fp) != 7) {
163*0fca8acaSbluhm warnx("failed seeking backward. (23)");
164ee8af14aSmpi failures++;
165ee8af14aSmpi }
166ee8af14aSmpi
1672b1dab59Sguenther if (fseek(fp, 5, SEEK_CUR) != 0) {
168384a789dSyasuoka warnx("failed to fseek. (24)");
169384a789dSyasuoka failures++;
170384a789dSyasuoka }
171384a789dSyasuoka
1722b1dab59Sguenther if (fclose(fp) == EOF) {
173384a789dSyasuoka warnx("fclose failed. (25)");
1742b1dab59Sguenther failures++;
1752b1dab59Sguenther }
1762b1dab59Sguenther
1772b1dab59Sguenther if (size != 12) {
178384a789dSyasuoka warnx("failed, size %zu should be %u. (26)",
1792b1dab59Sguenther size, 12);
1802b1dab59Sguenther failures++;
1812b1dab59Sguenther }
1822b1dab59Sguenther
18323468c0eSmpi free(buf);
18423468c0eSmpi
18523468c0eSmpi return (failures);
18623468c0eSmpi }
187