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); 141) Attempt to create file that already exists - EEXIST 152) Attempt to open a directory for writing - EISDIR 163) Pathname does not exist - ENOENT 174) Open for write but no write permission - EACCES 18 19read(int fd, void *buf, size_t count); 201) Read using invalid file descriptor - EBADF 21 22write(int fd, const void *buf, size_t count); 231) Write using invalid file descriptor - EBADF 242) Attempt to write to read-only file - EBADF 25 26lseek(int fildes, off_t offset, int whence); 271) Seeking on an invalid file descriptor - EBADF 282) Invalid "whence" (3rd param) value - EINVAL 29 30close(int fd); 311) Attempt to close an invalid file descriptor - EBADF 32 33stat(const char *file_name, struct stat *buf); 341) Pathname is a null string - ENOENT 352) Pathname does not exist - ENOENT 36 37fstat(int filedes, struct stat *buf); 381) Attempt to stat using an invalid file descriptor - EBADF 39 40isatty (int desc); 41Not applicable. We will test that it returns 1 when expected and a case 42where it should return 0. 43 44rename(const char *oldpath, const char *newpath); 451) newpath is an existing directory, but oldpath is not a directory. - EISDIR 462) newpath is a non-empty directory. - ENOTEMPTY or EEXIST 473) newpath is a subdirectory of old path. - EINVAL 484) oldpath does not exist. - ENOENT 49 50unlink(const char *pathname); 511) pathname does not have write access. - EACCES 522) pathname does not exist. - ENOENT 53 54time(time_t *t); 55Not applicable. 56 57system (const char * string); 581) See if shell available - returns 0 592) See if shell available - returns !0 603) Execute simple shell command - returns 0 614) Invalid string/command. - returns 127. */ 62 63static 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 76static void stop (void) {} 77 78/* A NULL string. We pass this to stat below instead of a NULL 79 literal to avoid -Wnonnull warnings. */ 80const char *null_str; 81 82void 83test_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 142void 143test_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 183void 184test_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 215void 216test_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 257void 258test_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 283void 284test_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 318void 319test_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 349void 350test_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 377char sys[1512]; 378 379void 380test_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 411void 412test_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 464char name[1256]; 465 466void 467test_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 506void 507test_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 522static const char * 523strerrno (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 559int 560main () 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