The C Programming Language P8.5
2013-01-11 13:48
267 查看
#include <fcntl.h> #define PERMS 0666 #define NULL 0 #define EOF (-1) #define BUFSIZE 1024 #define OPEN_MAX 20/* max #files open at once */ typedef struct _iobuf { int cnt; /* characters left */ char *ptr; /* next character position */ char *base; /* location of buffer */ int flag; /* mode of file access */ int fd; /* file descriptor */ } FILE; extern FILE _iob[OPEN_MAX]; #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2]) enum _flags { _READ = 01, /* file open for reading */ _WRITE = 02, /* file open for writing */ _UNBUF = 04, /* file is ubuffered */ _EOF = 010, /* EOF has occured on this file */ _ERR = 020 /* error occurred on this file */ }; int _fillbuf(FILE *); int _flushbuf(int, FILE *); FILE *fopen(char *name, char *mode); int fflush(FILE *); int fclose(FILE *); int fseek(FILE *fp, long offset, int origin); #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) 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 } }; int fseek(FILE *fp, long offset, int origin) { int result; if (!(fp->flag & _UNBUF) && fp->base != NULL) { if (fp->flag & _WRITE) { if (fflush(fp)) return EOF; } else if (fp->flag & _READ) { if (origin == 1) { if (offset >= 0 && offset <= fp->cnt) { fp->cnt -= offset; fp->ptr += offset; fp->flag &= ~_EOF; return 0; } else offset -= fp->cnt; } fp->cnt = 0; fp->ptr = fp->base; } } result = (lseek(fp->fd, offset, origin) < 0); if (result == 0) fp->flag &= ~_EOF; return result; } int _flush(FILE *fp) { return _flushbuf(EOF, fp); } int fflush(FILE *fp) { int retVal = 0; FILE *fpp = _iob; if (fp != NULL) { return _flush(fp); } else { while (fpp++ < _iob + OPEN_MAX) if (_flush(fpp) == EOF) retVal = EOF; } return retVal; } int fclose(FILE *fp) { if (fp == NULL) return EOF; if (fp < _iob || fp >= _iob + OPEN_MAX) return EOF; _flush(fp); if (fp->base != NULL) free(fp->base); fp->base = fp->ptr = NULL; fp->cnt = 0; fp->flag = 0; close(fp->fd); return 0; } int _fillbuf(FILE *fp) { int bufsize; if ((fp->flag & (_READ | _EOF | _ERR)) != _READ) return EOF; bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZE; 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 c, FILE *fp) { int bufsize; int num_written; if (fp < &_iob[0] || fp >= &_iob[OPEN_MAX]) return EOF; if ((fp->flag & (_WRITE | _EOF | _ERR)) != _WRITE) return EOF; bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZE; if (fp->base == NULL) { if ((fp->base = (char *) malloc(bufsize)) == NULL) { fp->flag |= _ERR; return EOF; } } else { num_written = fp->ptr - fp->base; if (write(fp->fd, fp->base, num_written) != num_written) { fp->flag |= _ERR; return EOF; } } fp->ptr = fp->base; fp->cnt = bufsize; if (--fp->cnt < 0) { if (fp->cnt == -1) fp->flag |= _EOF; else fp->flag |= _ERR; return EOF; } if(c!=EOF) *fp->ptr++ = c; return c; } 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)) 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; fp->ptr = NULL; fp->flag = (*mode == 'r') ? _READ : _WRITE; return fp; } int main(void) { int c; FILE *fp; fp = fopen("/root/apu/cl/c8/test1.c", "r"); fseek(fp, 2, 0); while ((c = getc(fp)) != EOF) { if (putchar(c) == EOF) exit(1); } fflush((FILE *) NULL); return 0; }
相关文章推荐
- The Go Programming Language. Notes.
- Getting Started - The Go Programming Language
- 再读《The C Programming language》 - 第一章 1.3 for语句
- The Go Programming Language Specification
- 再读《The C Programming Language》 第二章 2.1 变量类型
- The Swift Programming Language中文版 ----About Swift
- 再读《The C Programming Language》 第二章 2.3 表达式
- The kayword "new" of CPP programming language
- [精校版]The Swift Programming Language--语言指南--闭包
- 【重读】The C++ Programming Language/C++编程语言(一)
- The Swift Programming Language--语言指南--类型转换
- The Swift Programming Language--语言指南--基础部分
- 《The Scratch Programming Language and Environment》翻译
- 《The Swift Programming Language》中文版
- 《The C++ Programming Language, special edition》第6章6.6节中的一道有趣习题ch6.6-15
- The Java Programming Language
- 读The C++ programming language感受。
- 看了Code Conventions for the JavaTM Programming Language后自己总结一下,提醒自己
- The programming language 1-13 竖直方向直方图
- 【IOS编程 00】The Swift Programming Language