/* EXERCISE 8-2 */ /* THIS PROGRAM IS MODELED ON EXERCISE 8-1. */ /* BECAUSE THE FILE CONTROL BLOCK IS IN UNIX FORMAT THIS PROGRAM CAN */ /* NOT BE COMPILED AND TESTED IN THE WINDOWS ENVIRONMENT. */ #include <stdio.h> #include <io.h> #include <fcntl.h> #include <string.h> FILE *fopen(char *, char *); int _fillbuf(FILE *); main(int argc, char *argv[]) { FILE *fp; void filecopy(FILE *, FILE *); char *prog= argv[0]; /* PROGRAM NAME FOR ERRORS */ if (argc == 1) { /* NO ARGS; COPY STANDARD INPUT */ printf("ENTER INPUT FILE\n"); filecopy(stdin, stdout); } else while (--argc > 0) if ((fp = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "%s: CAN'T OPEN %s\n", prog, *argv); exit(1); } else { filecopy(fp, stdout); fclose(fp); } if (ferror(stdout)) { fprintf(stderr, "%s: ERROR WRITING stdout\n", prog); exit(2); } printf("nEND OF PROGRAM\n"); exit(0); } /* FILECOPY: COPY FILE ifd TO FILE ofd */ void filecopy(FILE *ifp, FILE *ofp) { int c; while ((c = getc(ifp)) !=EOF) putc(c, ofp); } #define PERMS 0666 /* RW FOR OWNER, GROUP, OTHERS */ struct flagbits { unsigned int read : 1; unsigned int write : 1; unsigned int unbuf : 1; unsigned int eof : 1; unsigned int err : 1; unsigned int fill1 : 11; } *fbits; /* FOPEN: OPEN FILE, RETURN FILE PTR */ FILE *fopen(char *name, char *mode) { int fd; FILE *fp; if (*mode != 'r' && *mode != 'w' && *mode != 'a') return NULL; for (fp = _iob; fp < _iob + OPEN_MAX; fp++) { fbits = (struct flagbits *) &fp->flag; if (!fbits->read && !fbits->write) break; /* FOUND FREE SLOT */ } if (fp >= _iob + OPEN_MAX) /* NO FREE SLOTS */ return NULL; if (*mode == 'w') fd = creat(name, PERMS); else if (*mode == 'a') { if ((fd = open(name, O_WRONLY, 0)) == -1) fd = creat(name, PERMS); lseek(fd, 0L, 2); } else fd = open(name, O_RDONLY, 0); if (fd == -1) /* COULDN'T ACCESS NAME */ return NULL; fp->fd = fd; if (*mode == 'r') /* SET BUFFER COUNT */ fp->cnt = 0; else fp->cnt = fbits->unbuf ? 1 : BUFSIZ; fp->base = NULL; fp->flag = (*mode == 'r') ? _READ : _WRITE; return fp; } /* _FILLBUF: ALLOCATE AND FILL INPUT BUFFER */ int _fillbuf(FILE *fp) { int bufsize; fbits = (struct flagbits *) &fp->flag; if (!fbits->read || fbits->eof || fbits->err) return EOF; bufsize = fbits->unbuf ? 1 : BUFSIZ; if (fp->base == NULL) /* NO BUFFER YET */ if ((fp->base = (char *) malloc(bufsize)) == NULL) return EOF; /* CAN'T GET BUFFER */ fp->ptr = fp->base; fp->cnt = read(fp->fd, fp->ptr, bufsize); if (--fp->cnt < 0) { if (fp->cnt == -1) fbits->eof = 1; else fbits->err = 1; fp->cnt = 0; return EOF; } return (unsigned char) *fp->ptr++; }