#include #include "files.h" #define PERMS 0666 FILE _iob[OPEN_MAX] = { /*r,w,u,f,e*/ { 0, (char *) 0, (char *) 0, {1,0,0,0,0}, 0}, { 0, (char *) 0, (char *) 0, {0,1,0,0,0}, 1}, { 0, (char *) 0, (char *) 0, {0,1,1,0,0}, 2}, }; /* seek to a specific location in fp */ int fseek(FILE *fp, long offset, int origin) { int rc = 0; int nc; if (fp->flags.is_read) { if (origin == 1) offset -= fp->cnt; rc = lseek(fp, offset, origin); fp->cnt = 0; } else if (fp->flags.is_write) { if ((nc = fp->ptr - fp->base) > 0) if (write(fp->fd, fp->base, nc) != nc) rc = -1; if (rc != -1) rc = lseek(fp, offset, origin); fp->cnt = 0; } return (rc == -1) ? -1 : 0; } /* write buffered data in fp to disk (dirty work) */ int _flush(FILE *fp) { int nc; /* make sure stream is valid */ if (fp < _iob || fp >= _iob + OPEN_MAX) return EOF; /* make sure stream is writable */ if (!fp->flags.is_write) return EOF; /* write any buffered data to disk */ nc = fp->ptr - fp->base; if (write(fp->fd, fp->base, nc) != nc) { fp->flags.is_err = 1; return EOF; } /* reset cnt and ptr */ fp->cnt = (fp->flags.is_unbuf) ? 1 : BUFSIZ; fp->ptr = fp->base; return 0; } /* write any buffered output in fp to disk */ int fflush(FILE *fp) { FILE *afp = _iob; if (fp != NULL) { return _flush(fp); } else while (afp++ < _iob + OPEN_MAX) _flush(afp); return 0; } /* close down and free up fp */ int fclose(FILE *fp) { int rc; /* make sure stream is valid */ if (fp < _iob || fp >= _iob + OPEN_MAX) return EOF; /* flush it */ rc = _flush(fp); /* free the buffer */ if (fp->base != NULL) free((void *) fp); /* reset ptr, cnt, and base */ fp->base = fp->ptr = NULL; fp->cnt = 0; /* turn off any flags */ fp->flags.is_write = fp->flags.is_read = fp->flags.is_unbuf = fp->flags.is_err = fp->flags.is_eof = 0; /* close stream */ close(fp->fd); return 0; } /* read in a block of fp and return first byte */ int _fillbuf(FILE *fp) { int bufsize; if (fp->flags.is_eof || fp->flags.is_err || !(fp->flags.is_read)) return EOF; bufsize = (fp->flags.is_unbuf) ? 1 : BUFSIZ; if (fp->base == NULL) if ((fp->base = (char *) malloc(bufsize)) == NULL) return EOF; fp->ptr = fp->base; fp->cnt = read(fp->fd, fp->ptr, bufsize); if (--fp->cnt < 0) { if (fp->cnt == -1) fp->flags.is_eof = 1; else fp->flags.is_err = 1; fp->cnt = 0; return EOF; } return (unsigned char) *fp->ptr++; } /* allocate buffer space for fp and write x */ int _flushbuf(int x, FILE *fp) { int bufsize; int n; /* make sure fp is valid */ if (fp < &_iob[0] || fp >= &_iob[OPEN_MAX]) return EOF; /* make sure we are able to write */ if (fp->flags.is_err || fp->flags.is_eof || !(fp->flags.is_write)) return EOF; /* buffered or unbuffered? */ if (fp->flags.is_unbuf) bufsize = 1; else bufsize = BUFSIZ; /* allocate buffer if not done already */ if (fp->base == NULL) { if ((fp->base = (char *) malloc(bufsize)) == NULL) { fp->flags.is_err = 1; return EOF; } } else { /* write any existing data to disk */ n = fp->ptr - fp->base; if (write(fp->fd, fp->base, n) != n) { fp->flags.is_err = 1; return EOF; } } /* reset ptr and cnt */ fp->ptr = fp->base; fp->cnt = bufsize; if (--fp->cnt < 0) { if (fp->cnt == -1) fp->flags.is_eof = 1; else fp->flags.is_err = 1; return EOF; } *fp->ptr++ = x; return x; } 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++) if ((fp->flags.is_read + fp->flags.is_write) == 0) break; if (fp >= _iob + OPEN_MAX) 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) return NULL; fp->fd = fd; fp->cnt = 0; fp->base = NULL; if (*mode == 'r') fp->flags.is_read = 1; else fp->flags.is_write = 1; return fp; }