1 /*
2 * fstat.c
3 *
4 * Created on: 2010-11-17
5 * Author: bernard
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <finsh.h>
10 #include <errno.h>
11 #include <sys/fcntl.h>
12 #include <sys/stat.h>
13
14 const char* text = "this is a test string\n";
libc_fstat()15 void libc_fstat()
16 {
17 int fd;
18 struct stat s;
19
20 fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0);
21 if (fd < 0)
22 {
23 printf("open failed\n");
24 return;
25 }
26
27 write(fd, text, strlen(text) + 1);
28 printf("begin: %d\n", lseek(fd, 0, SEEK_SET));
29 printf("end: %d\n", lseek(fd, 0, SEEK_END));
30
31 printf("fstat result: %d\n", fstat(fd, &s));
32 close(fd);
33 }
34 FINSH_FUNCTION_EXPORT(libc_fstat, fstat test for libc);
35
libc_lseek()36 void libc_lseek()
37 {
38 int fd;
39
40 fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0);
41 if (fd < 0)
42 {
43 printf("open failed\n");
44 return;
45 }
46
47 write(fd, text, strlen(text) + 1);
48 printf("begin: %d\n", lseek(fd, 0, SEEK_SET));
49 printf("end: %d\n", lseek(fd, 0, SEEK_END));
50 close(fd);
51 }
52 FINSH_FUNCTION_EXPORT(libc_lseek, lseek test for libc);
53
sleep(int tick)54 void sleep(int tick)
55 {
56 rt_thread_sleep(tick);
57 }
58
libc_fseek(void)59 int libc_fseek(void)
60 {
61 const char *tmpdir;
62 char *fname;
63 int fd;
64 FILE *fp;
65 const char outstr[] = "hello world!\n";
66 char strbuf[sizeof outstr];
67 char buf[200];
68 struct stat st1;
69 struct stat st2;
70 int result = 0;
71
72 tmpdir = getenv("TMPDIR");
73 if (tmpdir == NULL || tmpdir[0] == '\0')
74 tmpdir = "/tmp";
75
76 asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir);
77 if (fname == NULL)
78 {
79 fprintf(stderr, "cannot generate name for temporary file: %s\n",
80 strerror(errno));
81 return 1;
82 }
83
84 /* Create a temporary file. */
85 fd = mkstemp(fname);
86 if (fd == -1)
87 {
88 fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno));
89 return 1;
90 }
91
92 fp = fdopen(fd, "w+");
93 if (fp == NULL)
94 {
95 fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror(
96 errno));
97 return 1;
98 }
99 setbuffer(fp, strbuf, sizeof(outstr) - 1);
100
101 if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
102 {
103 printf("%d: write error\n", __LINE__);
104 result = 1;
105 goto out;
106 }
107
108 /* The EOF flag must be reset. */
109 if (fgetc(fp) != EOF)
110 {
111 printf("%d: managed to read at end of file\n", __LINE__);
112 result = 1;
113 }
114 else if (!feof(fp))
115 {
116 printf("%d: EOF flag not set\n", __LINE__);
117 result = 1;
118 }
119 if (fseek(fp, 0, SEEK_CUR) != 0)
120 {
121 printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
122 result = 1;
123 }
124 else if (feof(fp))
125 {
126 printf("%d: fseek() didn't reset EOF flag\n", __LINE__);
127 result = 1;
128 }
129
130 /* Do the same for fseeko(). */
131 if (fgetc(fp) != EOF)
132 {
133 printf("%d: managed to read at end of file\n", __LINE__);
134 result = 1;
135 }
136 else if (!feof(fp))
137 {
138 printf("%d: EOF flag not set\n", __LINE__);
139 result = 1;
140 }
141 if (fseeko(fp, 0, SEEK_CUR) != 0)
142 {
143 printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
144 result = 1;
145 }
146 else if (feof(fp))
147 {
148 printf("%d: fseek() didn't reset EOF flag\n", __LINE__);
149 result = 1;
150 }
151
152 /* Go back to the beginning of the file: absolute. */
153 if (fseek(fp, 0, SEEK_SET) != 0)
154 {
155 printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
156 result = 1;
157 }
158 else if (fflush(fp) != 0)
159 {
160 printf("%d: fflush() failed\n", __LINE__);
161 result = 1;
162 }
163 else if (lseek(fd, 0, SEEK_CUR) != 0)
164 {
165 int pos = lseek(fd, 0, SEEK_CUR);
166 printf("%d: lseek() returned different position, pos %d\n", __LINE__,
167 pos);
168 result = 1;
169 }
170 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
171 {
172 printf("%d: fread() failed\n", __LINE__);
173 result = 1;
174 }
175 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
176 {
177 printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
178 result = 1;
179 }
180
181 /* Now with fseeko. */
182 if (fseeko(fp, 0, SEEK_SET) != 0)
183 {
184 printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
185 result = 1;
186 }
187 else if (fflush(fp) != 0)
188 {
189 printf("%d: fflush() failed\n", __LINE__);
190 result = 1;
191 }
192 else if (lseek(fd, 0, SEEK_CUR) != 0)
193 {
194 printf("%d: lseek() returned different position\n", __LINE__);
195 result = 1;
196 }
197 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
198 {
199 printf("%d: fread() failed\n", __LINE__);
200 result = 1;
201 }
202 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
203 {
204 printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
205 result = 1;
206 }
207
208 /* Go back to the beginning of the file: relative. */
209 if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0)
210 {
211 printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
212 result = 1;
213 }
214 else if (fflush(fp) != 0)
215 {
216 printf("%d: fflush() failed\n", __LINE__);
217 result = 1;
218 }
219 else if (lseek(fd, 0, SEEK_CUR) != 0)
220 {
221 printf("%d: lseek() returned different position\n", __LINE__);
222 result = 1;
223 }
224 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
225 {
226 printf("%d: fread() failed\n", __LINE__);
227 result = 1;
228 }
229 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
230 {
231 printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
232 result = 1;
233 }
234
235 /* Now with fseeko. */
236 if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0)
237 {
238 printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
239 result = 1;
240 }
241 else if (fflush(fp) != 0)
242 {
243 printf("%d: fflush() failed\n", __LINE__);
244 result = 1;
245 }
246 else if (lseek(fd, 0, SEEK_CUR) != 0)
247 {
248 printf("%d: lseek() returned different position\n", __LINE__);
249 result = 1;
250 }
251 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
252 {
253 printf("%d: fread() failed\n", __LINE__);
254 result = 1;
255 }
256 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
257 {
258 printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
259 result = 1;
260 }
261
262 /* Go back to the beginning of the file: from the end. */
263 if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0)
264 {
265 printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
266 result = 1;
267 }
268 else if (fflush(fp) != 0)
269 {
270 printf("%d: fflush() failed\n", __LINE__);
271 result = 1;
272 }
273 else if (lseek(fd, 0, SEEK_CUR) != 0)
274 {
275 printf("%d: lseek() returned different position\n", __LINE__);
276 result = 1;
277 }
278 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
279 {
280 printf("%d: fread() failed\n", __LINE__);
281 result = 1;
282 }
283 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
284 {
285 printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
286 result = 1;
287 }
288
289 /* Now with fseeko. */
290 if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0)
291 {
292 printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
293 result = 1;
294 }
295 else if (fflush(fp) != 0)
296 {
297 printf("%d: fflush() failed\n", __LINE__);
298 result = 1;
299 }
300 else if (lseek(fd, 0, SEEK_CUR) != 0)
301 {
302 printf("%d: lseek() returned different position\n", __LINE__);
303 result = 1;
304 }
305 else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1)
306 {
307 printf("%d: fread() failed\n", __LINE__);
308 result = 1;
309 }
310 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0)
311 {
312 printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
313 result = 1;
314 }
315
316 if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
317 {
318 printf("%d: write error 2\n", __LINE__);
319 result = 1;
320 goto out;
321 }
322
323 if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
324 {
325 printf("%d: write error 3\n", __LINE__);
326 result = 1;
327 goto out;
328 }
329
330 if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
331 {
332 printf("%d: write error 4\n", __LINE__);
333 result = 1;
334 goto out;
335 }
336
337 if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1)
338 {
339 printf("%d: write error 5\n", __LINE__);
340 result = 1;
341 goto out;
342 }
343
344 if (fputc('1', fp) == EOF || fputc('2', fp) == EOF)
345 {
346 printf("%d: cannot add characters at the end\n", __LINE__);
347 result = 1;
348 goto out;
349 }
350
351 /* Check the access time. */
352 if (fstat(fd, &st1) < 0)
353 {
354 printf("%d: fstat64() before fseeko() failed\n\n", __LINE__);
355 result = 1;
356 }
357 else
358 {
359 sleep(1);
360
361 if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0)
362 {
363 printf("%d: fseek() after write characters failed\n", __LINE__);
364 result = 1;
365 goto out;
366 }
367 else
368 {
369
370 time_t t;
371 /* Make sure the timestamp actually can be different. */
372 sleep(1);
373 t = time(NULL);
374
375 if (fstat(fd, &st2) < 0)
376 {
377 printf("%d: fstat64() after fseeko() failed\n\n", __LINE__);
378 result = 1;
379 }
380 if (st1.st_ctime >= t)
381 {
382 printf("%d: st_ctime not updated\n", __LINE__);
383 result = 1;
384 }
385 if (st1.st_mtime >= t)
386 {
387 printf("%d: st_mtime not updated\n", __LINE__);
388 result = 1;
389 }
390 if (st1.st_ctime >= st2.st_ctime)
391 {
392 printf("%d: st_ctime not changed\n", __LINE__);
393 result = 1;
394 }
395 if (st1.st_mtime >= st2.st_mtime)
396 {
397 printf("%d: st_mtime not changed\n", __LINE__);
398 result = 1;
399 }
400 }
401 }
402
403 if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2
404 * (sizeof(outstr) - 1))
405 {
406 printf("%d: reading 2 records plus bits failed\n", __LINE__);
407 result = 1;
408 }
409 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp(
410 &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2
411 * (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1]
412 != '2')
413 {
414 printf("%d: reading records failed\n", __LINE__);
415 result = 1;
416 }
417 else if (ungetc('9', fp) == EOF)
418 {
419 printf("%d: ungetc() failed\n", __LINE__);
420 result = 1;
421 }
422 else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0)
423 {
424 printf("%d: fseek after ungetc failed\n", __LINE__);
425 result = 1;
426 }
427 else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2
428 * (sizeof(outstr) - 1))
429 {
430 printf("%d: reading 2 records plus bits failed\n", __LINE__);
431 result = 1;
432 }
433 else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp(
434 &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2
435 * (sizeof(outstr) - 1)] != '1')
436 {
437 printf("%d: reading records for the second time failed\n", __LINE__);
438 result = 1;
439 }
440 else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9')
441 {
442 printf("%d: unget character not ignored\n", __LINE__);
443 result = 1;
444 }
445 else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2')
446 {
447 printf("%d: unget somehow changed character\n", __LINE__);
448 result = 1;
449 }
450
451 fclose(fp);
452
453 fp = fopen(fname, "r");
454 if (fp == NULL)
455 {
456 printf("%d: fopen() failed\n\n", __LINE__);
457 result = 1;
458 }
459 else if (fstat(fileno(fp), &st1) < 0)
460 {
461 printf("%d: fstat64() before fseeko() failed\n\n", __LINE__);
462 result = 1;
463 }
464 else if (fseeko(fp, 0, SEEK_END) != 0)
465 {
466 printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
467 result = 1;
468 }
469 else if (ftello(fp) != st1.st_size)
470 {
471 printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
472 (size_t) st1.st_size, (size_t) ftello(fp));
473 result = 1;
474 }
475 else
476 printf("%d: SEEK_END works\n", __LINE__);
477 if (fp != NULL)
478 fclose(fp);
479
480 fp = fopen(fname, "r");
481 if (fp == NULL)
482 {
483 printf("%d: fopen() failed\n\n", __LINE__);
484 result = 1;
485 }
486 else if (fstat(fileno(fp), &st1) < 0)
487 {
488 printf("%d: fstat64() before fgetc() failed\n\n", __LINE__);
489 result = 1;
490 }
491 else if (fgetc(fp) == EOF)
492 {
493 printf("%d: fgetc() before fseeko() failed\n\n", __LINE__);
494 result = 1;
495 }
496 else if (fseeko(fp, 0, SEEK_END) != 0)
497 {
498 printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
499 result = 1;
500 }
501 else if (ftello(fp) != st1.st_size)
502 {
503 printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
504 (size_t) st1.st_size, (size_t) ftello(fp));
505 result = 1;
506 }
507 else
508 printf("%d: SEEK_END works\n", __LINE__);
509 if (fp != NULL)
510 fclose(fp);
511
512 out: unlink(fname);
513
514 return result;
515 }
516 FINSH_FUNCTION_EXPORT(libc_fseek, lseek test for libc);
517