/* 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++;
}