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"; 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 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 54 void sleep(int tick) 55 { 56 rt_thread_sleep(tick); 57 } 58 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