Хрестоматия по программированию на Си в Unix




Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 8


// вычислить логический номер блока по позиции RWptr. // BSIZE - это размер блока файловой системы, // эта константа определена в <sys/param.h>

daddr_t bno = offset / BSIZE; // если BSIZE == 1 Кб, то можно offset >> 10

u_pboff = offset % BSIZE; // это можно записать как offset & 01777

sz = BSIZE - u_pboff; // столько байт надо взять из этого блока, // начиная с позиции u_pboff.

if(count < sz) sz = count; u_pbsize = sz;

Если файл представляет собой устройство, то трансляция логических блоков в физические не производится - устройство представляет собой "сырой" диск без файлов и каталогов, т.е. обращение происходит сразу по физическому номеру блока:

if((ip->i_mode & IFMT) == IFBLK) // block device return bno; // raw disk // иначе провести пересчет:

rem = ip->i_size /*длина файла*/ - offset; // это остаток файла. if( rem < 0 ) rem = 0; // файл короче, чем заказано нами: if( rem < sz ) sz = rem; if((u_pbsize = sz) == 0) return (-1); // EOF

// и, собственно, замена логич. номера на физич. return ip->i_addr[bno]; }

Теперь рассмотрим алгоритм read. Параметры, начинающиеся с u_..., на самом деле передаются как статические через вспомогательные переменные в u-area процесса.

read(int fd, char *u_base, unsigned u_count){ unsigned srccount = u_count; struct file *fp = u_ofile[fd]; struct inode *ip = fp->f_inode; struct buf *bp; daddr_t bno; // очередной блок файла

// dev - устройство, // интерфейсом которого является файл-устройство, // или на котором расположен обычный файл. dev_t dev = (ip->i_mode & (IFCHR|IFBLK)) ? ip->i_rdev : ip->i_dev;

switch( ip->i_mode & IFMT ){

case IFCHR: // байто-ориентированное устройство (*cdevsw[major(dev)].d_read)(minor(dev)); // прочие параметры передаются через u-area

break;

case IFREG: // обычный файл case IFDIR: // каталог case IFBLK: // блочно-ориентированное устройство do{ bno = bmap(ip, fp->f_offset /*RWptr*/, u_count); if(u_pbsize==0 (long)bno < 0) break; // EOF bp = bread(dev, bno); // block read




Содержание  Назад  Вперед