xref: /nrf52832-nimble/rt-thread/examples/libc/file.c (revision 104654410c56c573564690304ae786df310c91fc)
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