1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/errno.h> 5 #include <sys/types.h> 6 #include <sys/fcntl.h> 7 #include <sys/stat.h> 8 #include <sys/time.h> 9 #include <errno.h> 10 #include <sys/wait.h> 11 #include <unistd.h> 12 #include <time.h> 13 /* TESTS : 14 * - open(const char *pathname, int flags, mode_t mode); 15 1) Attempt to create file that already exists - EEXIST 16 2) Attempt to open a directory for writing - EISDIR 17 3) Pathname does not exist - ENOENT 18 4) Open for write but no write permission - EACCES 19 20 read(int fd, void *buf, size_t count); 21 1) Read using invalid file descriptor - EBADF 22 23 write(int fd, const void *buf, size_t count); 24 1) Write using invalid file descriptor - EBADF 25 2) Attempt to write to read-only file - EBADF 26 27 lseek(int fildes, off_t offset, int whence); 28 1) Seeking on an invalid file descriptor - EBADF 29 2) Invalid "whence" (3rd param) value - EINVAL 30 31 close(int fd); 32 1) Attempt to close an invalid file descriptor - EBADF 33 34 stat(const char *file_name, struct stat *buf); 35 1) Pathname is a null string - ENOENT 36 2) Pathname does not exist - ENOENT 37 38 fstat(int filedes, struct stat *buf); 39 1) Attempt to stat using an invalid file descriptor - EBADF 40 41 isatty (int desc); 42 Not applicable. We will test that it returns 1 when expected and a case 43 where it should return 0. 44 45 rename(const char *oldpath, const char *newpath); 46 1) newpath is an existing directory, but oldpath is not a directory. - EISDIR 47 2) newpath is a non-empty directory. - ENOTEMPTY or EEXIST 48 3) newpath is a subdirectory of old path. - EINVAL 49 4) oldpath does not exist. - ENOENT 50 51 unlink(const char *pathname); 52 1) pathname does not have write access. - EACCES 53 2) pathname does not exist. - ENOENT 54 55 time(time_t *t); 56 Not applicable. 57 58 system (const char * string); 59 1) See if shell available - returns 0 60 2) See if shell available - returns !0 61 3) Execute simple shell command - returns 0 62 4) Invalid string/command. - returns 127. */ 63 64 static const char *strerrno (int err); 65 66 /* Note that OUTDIR is defined by the test suite. */ 67 #define FILENAME "foo.fileio.test" 68 #define RENAMED "bar.fileio.test" 69 #define NONEXISTANT "nofoo.fileio.test" 70 #define NOWRITE "nowrt.fileio.test" 71 #define TESTDIR1 "dir1.fileio.test" 72 #define TESTDIR2 "dir2.fileio.test" 73 #define TESTSUBDIR "dir1.fileio.test/subdir.fileio.test" 74 75 #define STRING "Hello World" 76 77 static void stop (void) {} 78 79 /* A NULL string. We pass this to stat below instead of a NULL 80 literal to avoid -Wnonnull warnings. */ 81 const char *null_str; 82 83 void 84 test_open (void) 85 { 86 int ret; 87 88 /* Test opening */ 89 errno = 0; 90 ret = open (OUTDIR FILENAME, O_CREAT | O_TRUNC | O_RDWR, S_IWUSR | S_IRUSR); 91 printf ("open 1: ret = %d, errno = %d %s\n", ret, errno, 92 ret >= 0 ? "OK" : ""); 93 94 if (ret >= 0) 95 close (ret); 96 stop (); 97 /* Creating an already existing file (created by fileio.exp) */ 98 errno = 0; 99 ret = open (OUTDIR FILENAME, O_CREAT | O_EXCL | O_WRONLY, S_IWUSR | S_IRUSR); 100 printf ("open 2: ret = %d, errno = %d %s\n", ret, errno, 101 strerrno (errno)); 102 if (ret >= 0) 103 close (ret); 104 stop (); 105 /* Open directory (for writing) */ 106 errno = 0; 107 ret = open (".", O_WRONLY); 108 printf ("open 3: ret = %d, errno = %d %s\n", ret, errno, 109 strerrno (errno)); 110 if (ret >= 0) 111 close (ret); 112 stop (); 113 /* Opening nonexistant file */ 114 errno = 0; 115 ret = open (NONEXISTANT, O_RDONLY); 116 printf ("open 4: ret = %d, errno = %d %s\n", ret, errno, 117 strerrno (errno)); 118 if (ret >= 0) 119 close (ret); 120 stop (); 121 /* Open for write but no write permission */ 122 errno = 0; 123 ret = open (OUTDIR NOWRITE, O_CREAT | O_RDONLY, S_IRUSR); 124 if (ret >= 0) 125 { 126 close (ret); 127 stop (); 128 errno = 0; 129 ret = open (OUTDIR NOWRITE, O_WRONLY); 130 printf ("open 5: ret = %d, errno = %d %s\n", ret, errno, 131 strerrno (errno)); 132 if (ret >= 0) 133 close (ret); 134 } 135 else 136 { 137 stop (); 138 printf ("open 5: ret = %d, errno = %d\n", ret, errno); 139 } 140 stop (); 141 } 142 143 void 144 test_write (void) 145 { 146 int fd, ret; 147 148 /* Test writing */ 149 errno = 0; 150 fd = open (OUTDIR FILENAME, O_WRONLY); 151 if (fd >= 0) 152 { 153 errno = 0; 154 ret = write (fd, STRING, strlen (STRING)); 155 printf ("write 1: ret = %d, errno = %d %s\n", ret, errno, 156 ret == strlen (STRING) ? "OK" : ""); 157 close (fd); 158 } 159 else 160 printf ("write 1: errno = %d\n", errno); 161 stop (); 162 /* Write using invalid file descriptor */ 163 errno = 0; 164 ret = write (999, STRING, strlen (STRING)); 165 printf ("write 2: ret = %d, errno = %d, %s\n", ret, errno, 166 strerrno (errno)); 167 stop (); 168 /* Write to a read-only file */ 169 errno = 0; 170 fd = open (OUTDIR FILENAME, O_RDONLY); 171 if (fd >= 0) 172 { 173 errno = 0; 174 ret = write (fd, STRING, strlen (STRING)); 175 printf ("write 3: ret = %d, errno = %d %s\n", ret, errno, 176 strerrno (errno)); 177 close (fd); 178 } 179 else 180 printf ("write 3: errno = %d\n", errno); 181 stop (); 182 } 183 184 void 185 test_read (void) 186 { 187 int fd, ret; 188 char buf[16]; 189 190 /* Test reading */ 191 errno = 0; 192 fd = open (OUTDIR FILENAME, O_RDONLY); 193 if (fd >= 0) 194 { 195 memset (buf, 0, 16); 196 errno = 0; 197 ret = read (fd, buf, 16); 198 buf[15] = '\0'; /* Don't trust anybody... */ 199 if (ret == strlen (STRING)) 200 printf ("read 1: %s %s\n", buf, !strcmp (buf, STRING) ? "OK" : ""); 201 else 202 printf ("read 1: ret = %d, errno = %d\n", ret, errno); 203 close (fd); 204 } 205 else 206 printf ("read 1: errno = %d\n", errno); 207 stop (); 208 /* Read using invalid file descriptor */ 209 errno = 0; 210 ret = read (999, buf, 16); 211 printf ("read 2: ret = %d, errno = %d %s\n", ret, errno, 212 strerrno (errno)); 213 stop (); 214 } 215 216 void 217 test_lseek (void) 218 { 219 int fd; 220 off_t ret = 0; 221 222 /* Test seeking */ 223 errno = 0; 224 fd = open (OUTDIR FILENAME, O_RDONLY); 225 if (fd >= 0) 226 { 227 errno = 0; 228 ret = lseek (fd, 0, SEEK_CUR); 229 printf ("lseek 1: ret = %ld, errno = %d, %s\n", (long) ret, errno, 230 ret == 0 ? "OK" : ""); 231 stop (); 232 errno = 0; 233 ret = lseek (fd, 0, SEEK_END); 234 printf ("lseek 2: ret = %ld, errno = %d, %s\n", (long) ret, errno, 235 ret == 11 ? "OK" : ""); 236 stop (); 237 errno = 0; 238 ret = lseek (fd, 3, SEEK_SET); 239 printf ("lseek 3: ret = %ld, errno = %d, %s\n", (long) ret, errno, 240 ret == 3 ? "OK" : ""); 241 close (fd); 242 } 243 else 244 { 245 printf ("lseek 1: ret = %ld, errno = %d %s\n", (long) ret, errno, 246 strerrno (errno)); 247 stop (); 248 printf ("lseek 2: ret = %ld, errno = %d %s\n", (long) ret, errno, 249 strerrno (errno)); 250 stop (); 251 printf ("lseek 3: ret = %ld, errno = %d %s\n", (long) ret, errno, 252 strerrno (errno)); 253 } 254 /* Seeking on an invalid file descriptor */ 255 stop (); 256 } 257 258 void 259 test_close (void) 260 { 261 int fd, ret; 262 263 /* Test close */ 264 errno = 0; 265 fd = open (OUTDIR FILENAME, O_RDONLY); 266 if (fd >= 0) 267 { 268 errno = 0; 269 ret = close (fd); 270 printf ("close 1: ret = %d, errno = %d, %s\n", ret, errno, 271 ret == 0 ? "OK" : ""); 272 } 273 else 274 printf ("close 1: errno = %d\n", errno); 275 stop (); 276 /* Close an invalid file descriptor */ 277 errno = 0; 278 ret = close (999); 279 printf ("close 2: ret = %d, errno = %d, %s\n", ret, errno, 280 strerrno (errno)); 281 stop (); 282 } 283 284 void 285 test_stat (void) 286 { 287 int ret; 288 struct stat st; 289 290 /* Test stat */ 291 errno = 0; 292 ret = stat (OUTDIR FILENAME, &st); 293 if (!ret) 294 printf ("stat 1: ret = %d, errno = %d %s\n", ret, errno, 295 st.st_size == 11 ? "OK" : ""); 296 else 297 printf ("stat 1: ret = %d, errno = %d\n", ret, errno); 298 stop (); 299 /* NULL pathname */ 300 errno = 0; 301 ret = stat (null_str, &st); 302 printf ("stat 2: ret = %d, errno = %d %s\n", ret, errno, 303 strerrno (errno)); 304 stop (); 305 /* Empty pathname */ 306 errno = 0; 307 ret = stat ("", &st); 308 printf ("stat 3: ret = %d, errno = %d %s\n", ret, errno, 309 strerrno (errno)); 310 stop (); 311 /* Nonexistant file */ 312 errno = 0; 313 ret = stat (NONEXISTANT, &st); 314 printf ("stat 4: ret = %d, errno = %d %s\n", ret, errno, 315 strerrno (errno)); 316 stop (); 317 } 318 319 void 320 test_fstat (void) 321 { 322 int fd, ret; 323 struct stat st; 324 325 /* Test fstat */ 326 errno = 0; 327 fd = open (OUTDIR FILENAME, O_RDONLY); 328 if (fd >= 0) 329 { 330 errno = 0; 331 ret = fstat (fd, &st); 332 if (!ret) 333 printf ("fstat 1: ret = %d, errno = %d %s\n", ret, errno, 334 st.st_size == 11 ? "OK" : ""); 335 else 336 printf ("fstat 1: ret = %d, errno = %d\n", ret, errno); 337 close (fd); 338 } 339 else 340 printf ("fstat 1: errno = %d\n", errno); 341 stop (); 342 /* Fstat using invalid file descriptor */ 343 errno = 0; 344 ret = fstat (999, &st); 345 printf ("fstat 2: ret = %d, errno = %d %s\n", ret, errno, 346 strerrno (errno)); 347 stop (); 348 } 349 350 void 351 test_isatty (void) 352 { 353 int fd; 354 355 /* Check std I/O */ 356 printf ("isatty 1: stdin %s\n", isatty (0) ? "yes OK" : "no"); 357 stop (); 358 printf ("isatty 2: stdout %s\n", isatty (1) ? "yes OK" : "no"); 359 stop (); 360 printf ("isatty 3: stderr %s\n", isatty (2) ? "yes OK" : "no"); 361 stop (); 362 /* Check invalid fd */ 363 printf ("isatty 4: invalid %s\n", isatty (999) ? "yes" : "no OK"); 364 stop (); 365 /* Check open file */ 366 fd = open (OUTDIR FILENAME, O_RDONLY); 367 if (fd >= 0) 368 { 369 printf ("isatty 5: file %s\n", isatty (fd) ? "yes" : "no OK"); 370 close (fd); 371 } 372 else 373 printf ("isatty 5: file couldn't open\n"); 374 stop (); 375 } 376 377 378 char sys[1512]; 379 380 void 381 test_system (void) 382 { 383 /* 384 * Requires test framework to switch on "set remote system-call-allowed 1" 385 */ 386 int ret; 387 388 /* Test for shell ('set remote system-call-allowed' is disabled 389 by default). */ 390 ret = system (NULL); 391 printf ("system 1: ret = %d %s\n", ret, ret == 0 ? "OK" : ""); 392 stop (); 393 /* Test for shell again (the testsuite will have enabled it now). */ 394 ret = system (NULL); 395 printf ("system 2: ret = %d %s\n", ret, ret != 0 ? "OK" : ""); 396 stop (); 397 /* This test prepares the directory for test_rename() */ 398 sprintf (sys, "mkdir -p %s/%s %s/%s", OUTDIR, TESTSUBDIR, OUTDIR, TESTDIR2); 399 ret = system (sys); 400 if (ret == 127) 401 printf ("system 3: ret = %d /bin/sh unavailable???\n", ret); 402 else 403 printf ("system 3: ret = %d %s\n", ret, ret == 0 ? "OK" : ""); 404 stop (); 405 /* Invalid command (just guessing ;-) ) */ 406 ret = system ("wrtzlpfrmpft"); 407 printf ("system 4: ret = %d %s\n", ret, 408 WEXITSTATUS (ret) == 127 ? "OK" : ""); 409 stop (); 410 } 411 412 void 413 test_rename (void) 414 { 415 int ret; 416 struct stat st; 417 418 /* Test rename */ 419 errno = 0; 420 ret = rename (OUTDIR FILENAME, OUTDIR RENAMED); 421 if (!ret) 422 { 423 errno = 0; 424 ret = stat (FILENAME, &st); 425 if (ret && errno == ENOENT) 426 { 427 errno = 0; 428 ret = stat (OUTDIR RENAMED, &st); 429 printf ("rename 1: ret = %d, errno = %d %s\n", ret, errno, 430 strerrno (errno)); 431 errno = 0; 432 } 433 else 434 printf ("rename 1: ret = %d, errno = %d\n", ret, errno); 435 } 436 else 437 printf ("rename 1: ret = %d, errno = %d\n", ret, errno); 438 stop (); 439 /* newpath is existing directory, oldpath is not a directory */ 440 errno = 0; 441 ret = rename (OUTDIR RENAMED, OUTDIR TESTDIR2); 442 printf ("rename 2: ret = %d, errno = %d %s\n", ret, errno, 443 strerrno (errno)); 444 stop (); 445 /* newpath is a non-empty directory */ 446 errno = 0; 447 ret = rename (OUTDIR TESTDIR2, OUTDIR TESTDIR1); 448 printf ("rename 3: ret = %d, errno = %d %s\n", ret, errno, 449 strerrno (errno)); 450 stop (); 451 /* newpath is a subdirectory of old path */ 452 errno = 0; 453 ret = rename (OUTDIR TESTDIR1, OUTDIR TESTSUBDIR); 454 printf ("rename 4: ret = %d, errno = %d %s\n", ret, errno, 455 strerrno (errno)); 456 stop (); 457 /* oldpath does not exist */ 458 errno = 0; 459 ret = rename (OUTDIR NONEXISTANT, OUTDIR FILENAME); 460 printf ("rename 5: ret = %d, errno = %d %s\n", ret, errno, 461 strerrno (errno)); 462 stop (); 463 } 464 465 char name[1256]; 466 467 void 468 test_unlink (void) 469 { 470 int ret; 471 472 /* Test unlink */ 473 errno = 0; 474 ret = unlink (OUTDIR RENAMED); 475 printf ("unlink 1: ret = %d, errno = %d %s\n", ret, errno, 476 strerrno (errno)); 477 stop (); 478 /* No write access */ 479 sprintf (name, "%s/%s/%s", OUTDIR, TESTDIR2, FILENAME); 480 errno = 0; 481 ret = open (name, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR); 482 if (ret >= 0) 483 { 484 sprintf (sys, "chmod -w %s/%s", OUTDIR, TESTDIR2); 485 ret = system (sys); 486 if (!ret) 487 { 488 errno = 0; 489 ret = unlink (name); 490 printf ("unlink 2: ret = %d, errno = %d %s\n", ret, errno, 491 strerrno (errno)); 492 } 493 else 494 printf ("unlink 2: ret = %d chmod failed, errno= %d\n", ret, errno); 495 } 496 else 497 printf ("unlink 2: ret = %d, errno = %d\n", ret, errno); 498 stop (); 499 /* pathname doesn't exist */ 500 errno = 0; 501 ret = unlink (OUTDIR NONEXISTANT); 502 printf ("unlink 3: ret = %d, errno = %d %s\n", ret, errno, 503 strerrno (errno)); 504 stop (); 505 } 506 507 void 508 test_time (void) 509 { 510 time_t ret, t; 511 512 errno = 0; 513 ret = time (&t); 514 printf ("time 1: ret = %ld, errno = %d, t = %ld %s\n", (long) ret, errno, (long) t, ret == t ? "OK" : ""); 515 stop (); 516 errno = 0; 517 ret = time (NULL); 518 printf ("time 2: ret = %ld, errno = %d, t = %ld %s\n", 519 (long) ret, errno, (long) t, ret >= t && ret < t + 10 ? "OK" : ""); 520 stop (); 521 } 522 523 static const char * 524 strerrno (int err) 525 { 526 switch (err) 527 { 528 case 0: return "OK"; 529 #ifdef EACCES 530 case EACCES: return "EACCES"; 531 #endif 532 #ifdef EBADF 533 case EBADF: return "EBADF"; 534 #endif 535 #ifdef EEXIST 536 case EEXIST: return "EEXIST"; 537 #endif 538 #ifdef EFAULT 539 case EFAULT: return "EFAULT"; 540 #endif 541 #ifdef EINVAL 542 case EINVAL: return "EINVAL"; 543 #endif 544 #ifdef EISDIR 545 case EISDIR: return "EISDIR"; 546 #endif 547 #ifdef ENOENT 548 case ENOENT: return "ENOENT"; 549 #endif 550 #ifdef ENOTEMPTY 551 case ENOTEMPTY: return "ENOTEMPTY"; 552 #endif 553 #ifdef EBUSY 554 case EBUSY: return "EBUSY"; 555 #endif 556 default: return "E??"; 557 } 558 } 559 560 int 561 main () 562 { 563 /* Don't change the order of the calls. They partly depend on each other */ 564 test_open (); 565 test_write (); 566 test_read (); 567 test_lseek (); 568 test_close (); 569 test_stat (); 570 test_fstat (); 571 test_isatty (); 572 test_system (); 573 test_rename (); 574 test_unlink (); 575 test_time (); 576 return 0; 577 } 578