1 /* $OpenBSD: fmemopentest.c,v 1.4 2020/08/17 16:17:39 millert 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 int 26 simpletest(void) 27 { 28 FILE *s1, *s2; 29 char string[] = "fmemopen test string!"; 30 char buffer[1024], *buf = NULL; 31 size_t len; 32 int c, failures = 0; 33 34 s1 = fmemopen(string, strlen(string) + 1, "r"); 35 if (s1 == NULL) { 36 warn("unable to open a stream s1"); 37 return (1); 38 } 39 40 s2 = fmemopen(buf, 22, "w+"); 41 if (s2 == NULL) { 42 warn("unable to create a stream s2"); 43 fclose(s1); 44 return (1); 45 } 46 47 while ((c = fgetc(s1)) != EOF) 48 fputc(c, s2); 49 50 if (ftell(s2) != strlen(string) + 1) { 51 warnx("failed copy test (1)"); 52 failures++; 53 } 54 fclose(s1); 55 56 fseek(s2, 0, SEEK_SET); 57 if (ftell(s2) != 0) { 58 warnx("failed seek test (2)"); 59 failures++; 60 } 61 62 len = fread(buffer, 1, sizeof(buffer) - 1, s2); 63 if (len != strlen(string) + 1) { 64 warnx("failed read test (3) %zu != %zu", 65 len, strlen(string) + 1); 66 failures++; 67 } 68 69 return (failures); 70 } 71 72 int 73 appendtest(const char *mode) 74 { 75 FILE *s1; 76 char string[] = "hello\0 test number 2"; 77 char buffer[256]; 78 size_t len; 79 int failures = 0; 80 81 s1 = fmemopen(string, 19, mode); 82 if (s1 == NULL) 83 return (1); 84 85 fseek(s1, 0, SEEK_SET); 86 if (ftell(s1) != 0) { 87 warnx("failed seek test [%s] (4)", mode); 88 failures++; 89 } 90 91 /* write should append even though seek position is 0 */ 92 len = fwrite(" world", 1, 6, s1); 93 if (len != 6) { 94 warnx("failed write test [%s] (5)", mode); 95 failures++; 96 } 97 98 if (ftell(s1) != strlen("hello world")) { 99 warnx("failed seek test [%s] (6)", mode); 100 failures++; 101 } 102 103 if (mode[1] == '+') { 104 fseek(s1, 0, SEEK_SET); 105 len = fread(buffer, 1, sizeof(buffer) - 1, s1); 106 if (len == 0 || strncmp(string, buffer, len)) { 107 warnx("failed compare test [%s] (7)", mode); 108 failures++; 109 } 110 } 111 112 if (strcmp(string, "hello world")) { 113 warnx("failed compare test [%s] (8)", mode); 114 failures++; 115 } 116 117 if (strcmp(string + strlen(string) + 1, "number 2")) { 118 warnx("failed compare test [%s] (9)", mode); 119 failures++; 120 } 121 122 return (failures); 123 } 124 125 int 126 updatetest(void) 127 { 128 FILE *s1; 129 char string[] = "bah, what a day"; 130 char buffer[256]; 131 size_t len; 132 int failures = 0; 133 134 s1 = fmemopen(string, 19, "r+"); 135 if (s1 == NULL) 136 return (1); 137 138 if (ftell(s1) != 0) { 139 warnx("failed seek test (10)"); 140 failures++; 141 } 142 143 len = fwrite("oh frabjous", 1, 11, s1); 144 if (len != 11) { 145 warnx("failed write test (11)"); 146 failures++; 147 } 148 149 fseek(s1, 0, SEEK_SET); 150 len = fread(buffer, 1, sizeof(buffer) - 1, s1); 151 if (len == 0 || strncmp(string, buffer, len)) { 152 warnx("failed compare test (12)"); 153 failures++; 154 } 155 156 if (strcmp(string, "oh frabjous day")) { 157 warnx("failed compare test (13)"); 158 failures++; 159 } 160 161 return (failures); 162 } 163 164 int 165 writetest(const char *mode) 166 { 167 FILE *s1; 168 char string[] = "super test number 3"; 169 char buffer[256]; 170 size_t len, slen; 171 int failures = 0; 172 173 slen = strlen(string) + 1; 174 175 s1 = fmemopen(string, slen, mode); 176 if (s1 == NULL) 177 return (1); 178 179 len = fwrite("short", 1, 5, s1); 180 if (len != strlen("short")) { 181 warnx("failed write test [%s] (14)", mode); 182 failures++; 183 } 184 fclose(s1); 185 186 s1 = fmemopen(string, slen, "r"); 187 if (s1 == NULL) { 188 warnx("failed open test [%s] (15)", mode); 189 failures++; 190 } 191 192 len = fread(buffer, 1, sizeof(buffer) - 1, s1); 193 if (len == 0 || strncmp(string, buffer, len)) { 194 warnx("failed compare test [%s] (16)", mode); 195 failures++; 196 } 197 198 if (strcmp(string, "short")) { 199 warnx("failed compare test [%s] (17)", mode); 200 failures++; 201 } 202 203 if (strcmp(string + strlen(string) + 1, "test number 3")) { 204 warnx("failed compare test [%s] (18)", mode); 205 failures++; 206 } 207 208 return (failures); 209 } 210 211 int 212 seektest(void) 213 { 214 FILE *s1; 215 char string[] = "long string for testing seek"; 216 size_t len, slen; 217 int failures = 0; 218 219 slen = strlen(string) + 1; 220 221 s1 = fmemopen(string, slen, "r"); 222 if (s1 == NULL) 223 return (1); 224 225 if (fseek(s1, 8, SEEK_SET) != 0) { 226 warnx("failed to fseek. (19)"); 227 failures++; 228 } 229 230 if (ftell(s1) != 8) { 231 warnx("failed seek test. (20)"); 232 failures++; 233 } 234 235 /* Try to seek backward */ 236 if (fseek(s1, -1, SEEK_CUR) != 0) { 237 warnx("failed to fseek. (21)"); 238 failures++; 239 } 240 241 if (ftell(s1) != 7) { 242 warnx("failed seeking backward. (22)"); 243 failures++; 244 } 245 246 return (failures); 247 } 248 249 int 250 main(void) 251 { 252 int failures = 0; 253 254 failures += simpletest(); 255 failures += appendtest("a"); 256 failures += appendtest("a+"); 257 failures += updatetest(); 258 failures += writetest("w"); 259 failures += writetest("w+"); 260 failures += seektest(); 261 262 return (failures); 263 } 264