fileio.c revision 1.6
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); 151) Attempt to create file that already exists - EEXIST 162) Attempt to open a directory for writing - EISDIR 173) Pathname does not exist - ENOENT 184) Open for write but no write permission - EACCES 19 20read(int fd, void *buf, size_t count); 211) Read using invalid file descriptor - EBADF 22 23write(int fd, const void *buf, size_t count); 241) Write using invalid file descriptor - EBADF 252) Attempt to write to read-only file - EBADF 26 27lseek(int fildes, off_t offset, int whence); 281) Seeking on an invalid file descriptor - EBADF 292) Invalid "whence" (3rd param) value - EINVAL 30 31close(int fd); 321) Attempt to close an invalid file descriptor - EBADF 33 34stat(const char *file_name, struct stat *buf); 351) Pathname is a null string - ENOENT 362) Pathname does not exist - ENOENT 37 38fstat(int filedes, struct stat *buf); 391) Attempt to stat using an invalid file descriptor - EBADF 40 41isatty (int desc); 42Not applicable. We will test that it returns 1 when expected and a case 43where it should return 0. 44 45rename(const char *oldpath, const char *newpath); 461) newpath is an existing directory, but oldpath is not a directory. - EISDIR 472) newpath is a non-empty directory. - ENOTEMPTY or EEXIST 483) newpath is a subdirectory of old path. - EINVAL 494) oldpath does not exist. - ENOENT 50 51unlink(const char *pathname); 521) pathname does not have write access. - EACCES 532) pathname does not exist. - ENOENT 54 55time(time_t *t); 56Not applicable. 57 58system (const char * string); 591) See if shell available - returns 0 602) See if shell available - returns !0 613) Execute simple shell command - returns 0 624) Invalid string/command. - returns 127. */ 63 64static 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 77static void stop (void) {} 78 79/* A NULL string. We pass this to stat below instead of a NULL 80 literal to avoid -Wnonnull warnings. */ 81const char *null_str; 82 83void 84test_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 143void 144test_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 184void 185test_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 216void 217test_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 258void 259test_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 284void 285test_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 319void 320test_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 350void 351test_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 378char sys[1512]; 379 380void 381test_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 412void 413test_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 465char name[1256]; 466 467void 468test_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 507void 508test_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 523static const char * 524strerrno (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 560int 561main () 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