1*d35e2a8fSmillert /* $OpenBSD: fmemopentest.c,v 1.4 2020/08/17 16:17:39 millert Exp $ */
242175e39Smpi
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 int
simpletest(void)2642175e39Smpi simpletest(void)
2723468c0eSmpi {
2823468c0eSmpi FILE *s1, *s2;
2942175e39Smpi char string[] = "fmemopen test string!";
3023468c0eSmpi char buffer[1024], *buf = NULL;
3123468c0eSmpi size_t len;
3242175e39Smpi int c, failures = 0;
3323468c0eSmpi
3442175e39Smpi s1 = fmemopen(string, strlen(string) + 1, "r");
3523468c0eSmpi if (s1 == NULL) {
3623468c0eSmpi warn("unable to open a stream s1");
3723468c0eSmpi return (1);
3823468c0eSmpi }
3923468c0eSmpi
4023468c0eSmpi s2 = fmemopen(buf, 22, "w+");
4123468c0eSmpi if (s2 == NULL) {
4223468c0eSmpi warn("unable to create a stream s2");
4323468c0eSmpi fclose(s1);
4423468c0eSmpi return (1);
4523468c0eSmpi }
4623468c0eSmpi
4723468c0eSmpi while ((c = fgetc(s1)) != EOF)
4823468c0eSmpi fputc(c, s2);
4923468c0eSmpi
5042175e39Smpi if (ftell(s2) != strlen(string) + 1) {
5123468c0eSmpi warnx("failed copy test (1)");
5223468c0eSmpi failures++;
5323468c0eSmpi }
5423468c0eSmpi fclose(s1);
5523468c0eSmpi
5623468c0eSmpi fseek(s2, 0, SEEK_SET);
5723468c0eSmpi if (ftell(s2) != 0) {
5823468c0eSmpi warnx("failed seek test (2)");
5923468c0eSmpi failures++;
6023468c0eSmpi }
6123468c0eSmpi
6223468c0eSmpi len = fread(buffer, 1, sizeof(buffer) - 1, s2);
6342175e39Smpi if (len != strlen(string) + 1) {
6442175e39Smpi warnx("failed read test (3) %zu != %zu",
6542175e39Smpi len, strlen(string) + 1);
6623468c0eSmpi failures++;
6723468c0eSmpi }
6823468c0eSmpi
6923468c0eSmpi return (failures);
7023468c0eSmpi }
7142175e39Smpi
7242175e39Smpi int
appendtest(const char * mode)73*d35e2a8fSmillert appendtest(const char *mode)
7442175e39Smpi {
7542175e39Smpi FILE *s1;
7642175e39Smpi char string[] = "hello\0 test number 2";
7742175e39Smpi char buffer[256];
7842175e39Smpi size_t len;
7942175e39Smpi int failures = 0;
8042175e39Smpi
81*d35e2a8fSmillert s1 = fmemopen(string, 19, mode);
8242175e39Smpi if (s1 == NULL)
8342175e39Smpi return (1);
8442175e39Smpi
8542175e39Smpi fseek(s1, 0, SEEK_SET);
8642175e39Smpi if (ftell(s1) != 0) {
87*d35e2a8fSmillert warnx("failed seek test [%s] (4)", mode);
8842175e39Smpi failures++;
8942175e39Smpi }
9042175e39Smpi
91*d35e2a8fSmillert /* write should append even though seek position is 0 */
92*d35e2a8fSmillert len = fwrite(" world", 1, 6, s1);
93*d35e2a8fSmillert if (len != 6) {
94*d35e2a8fSmillert warnx("failed write test [%s] (5)", mode);
9542175e39Smpi failures++;
9642175e39Smpi }
9742175e39Smpi
98*d35e2a8fSmillert if (ftell(s1) != strlen("hello world")) {
99*d35e2a8fSmillert warnx("failed seek test [%s] (6)", mode);
100*d35e2a8fSmillert failures++;
101*d35e2a8fSmillert }
102*d35e2a8fSmillert
103*d35e2a8fSmillert if (mode[1] == '+') {
104*d35e2a8fSmillert fseek(s1, 0, SEEK_SET);
105*d35e2a8fSmillert len = fread(buffer, 1, sizeof(buffer) - 1, s1);
106*d35e2a8fSmillert if (len == 0 || strncmp(string, buffer, len)) {
107*d35e2a8fSmillert warnx("failed compare test [%s] (7)", mode);
108*d35e2a8fSmillert failures++;
109*d35e2a8fSmillert }
110*d35e2a8fSmillert }
111*d35e2a8fSmillert
11242175e39Smpi if (strcmp(string, "hello world")) {
113*d35e2a8fSmillert warnx("failed compare test [%s] (8)", mode);
11442175e39Smpi failures++;
11542175e39Smpi }
11642175e39Smpi
11742175e39Smpi if (strcmp(string + strlen(string) + 1, "number 2")) {
118*d35e2a8fSmillert warnx("failed compare test [%s] (9)", mode);
11942175e39Smpi failures++;
12042175e39Smpi }
12142175e39Smpi
12242175e39Smpi return (failures);
12342175e39Smpi }
12442175e39Smpi
12542175e39Smpi int
updatetest(void)126*d35e2a8fSmillert updatetest(void)
127*d35e2a8fSmillert {
128*d35e2a8fSmillert FILE *s1;
129*d35e2a8fSmillert char string[] = "bah, what a day";
130*d35e2a8fSmillert char buffer[256];
131*d35e2a8fSmillert size_t len;
132*d35e2a8fSmillert int failures = 0;
133*d35e2a8fSmillert
134*d35e2a8fSmillert s1 = fmemopen(string, 19, "r+");
135*d35e2a8fSmillert if (s1 == NULL)
136*d35e2a8fSmillert return (1);
137*d35e2a8fSmillert
138*d35e2a8fSmillert if (ftell(s1) != 0) {
139*d35e2a8fSmillert warnx("failed seek test (10)");
140*d35e2a8fSmillert failures++;
141*d35e2a8fSmillert }
142*d35e2a8fSmillert
143*d35e2a8fSmillert len = fwrite("oh frabjous", 1, 11, s1);
144*d35e2a8fSmillert if (len != 11) {
145*d35e2a8fSmillert warnx("failed write test (11)");
146*d35e2a8fSmillert failures++;
147*d35e2a8fSmillert }
148*d35e2a8fSmillert
149*d35e2a8fSmillert fseek(s1, 0, SEEK_SET);
150*d35e2a8fSmillert len = fread(buffer, 1, sizeof(buffer) - 1, s1);
151*d35e2a8fSmillert if (len == 0 || strncmp(string, buffer, len)) {
152*d35e2a8fSmillert warnx("failed compare test (12)");
153*d35e2a8fSmillert failures++;
154*d35e2a8fSmillert }
155*d35e2a8fSmillert
156*d35e2a8fSmillert if (strcmp(string, "oh frabjous day")) {
157*d35e2a8fSmillert warnx("failed compare test (13)");
158*d35e2a8fSmillert failures++;
159*d35e2a8fSmillert }
160*d35e2a8fSmillert
161*d35e2a8fSmillert return (failures);
162*d35e2a8fSmillert }
163*d35e2a8fSmillert
164*d35e2a8fSmillert int
writetest(const char * mode)165*d35e2a8fSmillert writetest(const char *mode)
16642175e39Smpi {
16742175e39Smpi FILE *s1;
16842175e39Smpi char string[] = "super test number 3";
16942175e39Smpi char buffer[256];
17042175e39Smpi size_t len, slen;
17142175e39Smpi int failures = 0;
17242175e39Smpi
17342175e39Smpi slen = strlen(string) + 1;
17442175e39Smpi
175*d35e2a8fSmillert s1 = fmemopen(string, slen, mode);
17642175e39Smpi if (s1 == NULL)
17742175e39Smpi return (1);
17842175e39Smpi
17942175e39Smpi len = fwrite("short", 1, 5, s1);
18042175e39Smpi if (len != strlen("short")) {
181*d35e2a8fSmillert warnx("failed write test [%s] (14)", mode);
18242175e39Smpi failures++;
18342175e39Smpi }
18442175e39Smpi fclose(s1);
18542175e39Smpi
18642175e39Smpi s1 = fmemopen(string, slen, "r");
18742175e39Smpi if (s1 == NULL) {
188*d35e2a8fSmillert warnx("failed open test [%s] (15)", mode);
18942175e39Smpi failures++;
19042175e39Smpi }
19142175e39Smpi
19242175e39Smpi len = fread(buffer, 1, sizeof(buffer) - 1, s1);
193*d35e2a8fSmillert if (len == 0 || strncmp(string, buffer, len)) {
194*d35e2a8fSmillert warnx("failed compare test [%s] (16)", mode);
19542175e39Smpi failures++;
19642175e39Smpi }
19742175e39Smpi
19842175e39Smpi if (strcmp(string, "short")) {
199*d35e2a8fSmillert warnx("failed compare test [%s] (17)", mode);
20042175e39Smpi failures++;
20142175e39Smpi }
20242175e39Smpi
20342175e39Smpi if (strcmp(string + strlen(string) + 1, "test number 3")) {
204*d35e2a8fSmillert warnx("failed compare test [%s] (18)", mode);
20542175e39Smpi failures++;
20642175e39Smpi }
20742175e39Smpi
20842175e39Smpi return (failures);
20942175e39Smpi }
21042175e39Smpi
21142175e39Smpi int
seektest(void)212ee8af14aSmpi seektest(void)
213ee8af14aSmpi {
214ee8af14aSmpi FILE *s1;
215ee8af14aSmpi char string[] = "long string for testing seek";
216ee8af14aSmpi size_t len, slen;
217ee8af14aSmpi int failures = 0;
218ee8af14aSmpi
219ee8af14aSmpi slen = strlen(string) + 1;
220ee8af14aSmpi
221ee8af14aSmpi s1 = fmemopen(string, slen, "r");
222ee8af14aSmpi if (s1 == NULL)
223ee8af14aSmpi return (1);
224ee8af14aSmpi
225ee8af14aSmpi if (fseek(s1, 8, SEEK_SET) != 0) {
226*d35e2a8fSmillert warnx("failed to fseek. (19)");
227ee8af14aSmpi failures++;
228ee8af14aSmpi }
229ee8af14aSmpi
230ee8af14aSmpi if (ftell(s1) != 8) {
231*d35e2a8fSmillert warnx("failed seek test. (20)");
232ee8af14aSmpi failures++;
233ee8af14aSmpi }
234ee8af14aSmpi
235ee8af14aSmpi /* Try to seek backward */
236ee8af14aSmpi if (fseek(s1, -1, SEEK_CUR) != 0) {
237*d35e2a8fSmillert warnx("failed to fseek. (21)");
238ee8af14aSmpi failures++;
239ee8af14aSmpi }
240ee8af14aSmpi
241ee8af14aSmpi if (ftell(s1) != 7) {
242*d35e2a8fSmillert warnx("failed seeking backward. (22)");
243ee8af14aSmpi failures++;
244ee8af14aSmpi }
245ee8af14aSmpi
246ee8af14aSmpi return (failures);
247ee8af14aSmpi }
248ee8af14aSmpi
249ee8af14aSmpi int
main(void)25042175e39Smpi main(void)
25142175e39Smpi {
25242175e39Smpi int failures = 0;
25342175e39Smpi
25442175e39Smpi failures += simpletest();
255*d35e2a8fSmillert failures += appendtest("a");
256*d35e2a8fSmillert failures += appendtest("a+");
25742175e39Smpi failures += updatetest();
258*d35e2a8fSmillert failures += writetest("w");
259*d35e2a8fSmillert failures += writetest("w+");
260ee8af14aSmpi failures += seektest();
26142175e39Smpi
26242175e39Smpi return (failures);
26342175e39Smpi }
264