- 论坛徽章:
- 0
|
回复 5# rubylc_unix
据我现在的理解,cnt指缓冲区内剩余到字符数,对于_fillbuf和_flushbuf有不同到意思,在fillbuf中指已存入缓冲区的字符数,在flushbuf中指缓冲区剩余的空位置,原代码如下:- #include <unistd.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #undef NULL
- #define NULL 0
- #define EOF (-1)
- #define BUFSIZ 1024
- #define OPEN_MAX 20
- enum _flags {
- _READ = 01,
- _WRITE = 02,
- _UNBUF = 04,
- _EOF = 010,
- _ERR = 020,
- };
- typedef struct _iobuf {
- int cnt;
- char *ptr;
- char *base;
- int flag;
- int fd;
- } FILE;
- extern FILE _iob[OPEN_MAX];
- FILE _iob[OPEN_MAX] = {
- {0, (char *)0, (char *)0, _READ, 0},
- {0, (char *)0, (char *)0, _WRITE, 1},
- {0, (char *)0, (char *)0, _WRITE | _UNBUF, 2},
- };
- #define stdin (&_iob[0])
- #define stdout (&_iob[1])
- #define stderr (&_iob[2])
- int _fillbuf(FILE *);
- int _flushbuf(int, FILE *);
- #define feof(p) (((p)->flag & _EOF) != 0)
- #define ferror(p) (((p)->flag & _ERR) != 0)
- #define fileno(p) ((p)->fd)
- #define getc(p) (--(p)->cnt >= 0 \
- ? (unsigned char)*(p)->ptr++ : _fillbuf(p))
- #define putc(x,p) (--(p)->cnt >= 0 \
- ? *(p)->ptr++ = (x) : _flushbuf((x), p))
- #define getchar() getc(stdin)
- #define putchar(x) putc((x), stdout)
- #define PERMS 0777
- 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->flag & (_READ | _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)) == -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;
- fp->flag = (*mode == 'r') ? _READ : _WRITE;
- return fp;
- }
- int _fillbuf(FILE *fp)
- {
- int bufsize;
- if ((fp->flag & (_READ | _EOF | _ERR)) != _READ)
- return EOF;
- bufsize = (fp->flag & _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->flag |= _EOF;
- else
- fp->flag |= _ERR;
- fp->cnt = 0;
- return EOF;
- }
- return (unsigned char) *fp->ptr++;
- }
- int _flushbuf(int x, FILE *fp)
- {
- unsigned nc;
- int bufsize;
- if (fp < _iob || fp > _iob + OPEN_MAX)
- return EOF;
- if ((fp->flag & (_WRITE | _ERR)) != _WRITE)
- return EOF;
- bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ;
- if (fp->base == NULL) {
- if ((fp->base = (char *)malloc(bufsize)) == NULL) {
- fp->flag |= _ERR;
- return EOF;
- }
- } else {
- nc = fp->ptr - fp->base;
- if (write(fp->fd, fp->base, nc) != nc) {
- fp->flag |= _ERR;
- return EOF;
- }
- }
- fp->ptr = fp->base;
- *fp->ptr++ = x;
- fp->cnt = bufsize - 1;
- return x;
- }
- int main()
- {
- FILE *fp;
- int c;
- if ((fp = fopen("test.c", "r")) == NULL)
- return EOF;
- while ((c = getc(fp)) != EOF) {
- //write(1, &c, 1);
- putchar(c);
- }
- }
复制代码 |
|