_EOF = 010, /* в данном файле встретился EOF */
_ERR = 020 /* в данном файле встретилась ошибка */
};
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)
Макрос
Хотя в деталях ввод-вывод здесь не рассматривается, мы все же привели полное определение
Теперь можно написать функцию
#include
#include "syscalls.h"
#define PERMS 0666 /* RW для собственника, группы и проч. */
/* fopen: открывает файл, возвращает файловый указатель */
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, 0)) == -1)
fd = creat(name, PERMS);
lseek(fd, 0L, 2);
} else
fd = open(name, O_RDONLY, 0);
if (fd == -1) /* невозможен доступ по имени name */
return NULL;
fp->fd = fd;
fp->cnt = 0;
fp->base = NULL;
fp->flag = (*mode == 'r') ? _READ : _WRITE;
return fp;
}
Приведенная здесь версия
Для любого файла в момент первого обращения к нему с помощью макровызова
После получения области памяти для буфера
#include "syscalls.h"
/* _fillbuf: запрос памяти и заполнение буфера */
int _fillbuf(FILE *fp)
{
int bufsize;
if ((fp->flag & ( _READ | _EOF | _ERR )) != _READ)