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