|
Программирование >> Структура ядра и системные вызовы
функция regfile::unlock остбожаает область файла, связанного с объектом класса regfile. Начальным адресом освобождаемой области является текущий указатель позиции в файле. Его можно установить функцией fstream:iseekg. Размер заблокированной области (в байтах) задается аргументом len. Функция regfile::ип1оск по умолчанию является неблокирующей и возвращает то же значение, что и fcntl в режиме снятия блокировки с файлов. Функция regfile::getlock запрашивает информацию о режиме блокировки указанной в вызове этой функции области файла, связанного с объектом класса regfile. Аргумент Ickjype показывает, о какой блокировке необходима информация, - о блокировке чтения {Ickjtype = ios::in) или о блокировке записи {Ickjype = ios::out). Начальным адресом области является текущий указатель позиции в файле. Его можно установить с помощью функции fstream::seekg. Размер области (в байтах) задается аргументом len. Функция regfile::getlock является неблокирующей и возвращает то же значение, что и функция fcntl. При успешном выполнении вызова функции regfile::getlock аргумент flck будет содержать информацию о блокировках для данной области файла. Класс regfile обеспечивает полную инкапсуляцию всех функций, предусмотренных в UNIX и POSIX для обычных файлов. Он также упрощает API блокировки и освобождения файлов, чтобы для работы с функциями reg-file::lock, regfile::unlock и regfile::getlock пользователям достаточно было знать только интерфейс класса fstream. Ниже приведена программа test regfile.C, которая иллюстрирует использование объекта regfile для создания временного файла foo, блокирует весь этот файл по записи, инициализирует его содержимое данными из файла /etc/passwd, освобождает первые 10 байтов файла и, наконец, удаляет его; ♦ include regfile.h int main {) ifstream ifs { /etc/passwd ); cliar buf [256],- regfile rfile{ foo ,ios::out I ios::in, 0777); определить объект класса regfile заблокировать файл по записи rfile buf endl; установить указатель позиции в начало файла разблокировать первые 10 байтов rfile. 1ос)с {ios: :out,0) ; while {ifs.getline{buf,256)) rfile.see)cg(0,ios: :beg) ; rfile.unloc)c{10); rfile. remove() ; return 0; файла удалить файл 7.9. Класс dirfile для каталогов Класс dirfile определен с целью инкапсуляции всех функций, предусмотренных для файлов каталогов в UNIX и POSIX. В частности, в классе dirfile определены функции create, open, read, tellg, seekg, close и remove, которые используют API каталогов, применяемые в UNIX и POSIX. Класс diffile определяется следующим образом: #ifndef DIRFILE H ♦define DIRFILE H finclude filebase.h finclude <dirent.h> finclude <string.h> /* класс, инкапсулирующей свойства обычных файловых объектов POSIX и UNIX */ class dirfile DIR *dir Ptr; char *filename; public: dirfile(const char* fn) { dir Ptr = opendir{fn); filename = new char[strlen{fn)+1]; strcpy{filename,fn); -dirfile{) ( if (dir Ptr) close(); delete filename; int close 0 ( return {dir ptr) ? closedir{dlr Ptr) : -1; ]; int create( const char* fn, mode t prot) { return m)cdir {fn,prot) ; ); int open{const char* fn) { dir Ptr=opendir{fn); return dir Ptr ? 0 : -1; }; int read{char* buf, int size) { struct dirent *dp = readdir{dir ptr); if {dp) strncpy{buf,dp->d name,size); return {dp)? strlen(dp->d name) : 0; ); off t tellgO { return telldir(dir Ptr); ); . void seekg( off t ofs ) ( seekdir(dir ptr, ofs); ]; int remove 0 { return rmdir(filename); ]; #endlf /* dirfile.h */ ,: Для создания файлов каталогов в классе dirfile используется API mkdir. Кроме того, для открытия и чтения каталогов применяются API opendir и readdir Объект класса dirfile может трактоваться пользователем почти так же, как обычный файловый объект. Единственное их различие состоит в том. что в объекте класса dirfile ничего не предусмотрено для операций записи. Функции dirfile::tellg и dirfiler.seekg, используя UNIX-интерфейсы telldir и seekdir, обеспечивают произвольный доступ к любой записи каталога. Наконец, функция dirfile:-.close с помощью closedir закрывает файл каталога, а функция dirfile::remove, применив API rmdir, удаляет этот файл из файловой системы. Ниже приведена программа testjdirfile. С, которая открывает каталог /etc и выводит на экран перечень всех находящихся в нем файлов: ♦include dirfile.h int main О dirfile edir( /etc ) ; создать объект класса dirfile для /etc char buf[256]; while (edir. read (buf, 256)) показать файлы, имекщиеся в каталоге /etc cout buf endl; edir.close 0; закрыть каталог return 0; 7.10. Класс pipefile для FIFO-файлов Файловый объект типа FIFO отличается от объекта класса filebase тем, что создается в процессе выполнения программы и функции tellg и seekg для него не приемлемы. Класс pipefile, определение которого приведено ниже, инкапсулирует все свойства FIFO-файлов #ifndef PIPEFILE H ♦define PIPEFILE H ♦include filebase.h /* класс, инкапсулирующий свойства обычных FIFO-файловых объектов POSIX и UNIX */ class pipefile. .; : public filebasds s,r { public: ;* pipefile (const char* fn, int flags, int prot) ; filebase (fn, flags,prot) . ! .{]; У,. int create( const char* fn, mode t prot) ( return m)<fifo (fn,prot) ; ]; streampos tellg () { return (streampos)-1; }; ♦endif /* pipefile.h */ Ниже приведена программа testjipefile.C, которая создает FIFO-файл с именем FIFO, открывает его для чтения (если argc = 1) или для записи (если argc > 1). Затем программа читает или записывает данные с использованием FIFO-файла и закрывает его: finclude pipefile.h int main( int argc, char* argv[] ) pipefile nfifo( FIFO , argc==l ? ios::in : ios::out, 0755); if (argc > 1) записывающий процесс cout writer process Write: argv{l] << endl; nfifo.write(argv{l],strlen(argv[l])+1); write data to FIFO } else читающий процесс char buf[256]; nfifo.read(buf,256); прочитать данные из FIFO-файла cout read from FIFO: buf endl; nfifo.close 0; return 0; закрыть FIFO-файл Путем повторного выполнения этой программы можно создать два процесса, которые будут взаимодействовать через FIFO-файл. Сначала программа выполняется без аргумента командной строки и создает читающий процесс, затем запускается с аргументом командной строки, который создает записывающий процесс. После того как оба процесса будут созданы, записывающий процесс запищет свой аргумент командной строки в FIFO-файл, а читающий процесс прочитает этот аргумент из файла и выдаст его на стандартный вывод. Ниже приведены результаты выполнения этой программы: % СС -о test pipefile test pipefile.С % test pipefile & ♦ создать читающий процесс % test pipefile hello ♦ создать записывающий процесс writer process write: hello ♦ выходная информация записывающего процесса read from FIFO: hello ♦ выходная информация читающего процесса 7.11. Класс devfile для файлов устройств Объект типа файл устройства обладает всеми свойствами обьптого файлового объекта, за исключением метода создания. Кроме того, применение функций tellg, seekg, lock, lockw, unlock и getlock для байт-орие>гги-рованных файлов устройств не допустимо. Определенный ниже класс devfile инкапсулирует все свойства UNIX-файлов устройств: fifndef DEVFILE H fdefine DEVFILE H finclude regfile.h /* класс, инкапсулирующий свойства файлов устройств POSIX- и UNIX-систем */. class devfile : public regfile ♦endif public: devfile(const char* fn, int flags, int prot) : regfile(fn,flags,prot) {} ; int create(const char* fn, mode t prot, int major no, int minor no, char type=c} { if (type==c) return mlcnod{fn, S IFCHR prot, (major no 8) minor no} ; else return mlcnod{fn, S IFBLK I prot, {major no < 8} I minor no}; streampos tellgO ( if {file type {} ==CHAR FILE) return (streampos)-1; else return fstream:: tellg{} , }; istreams seelcg( streampos ofs, seelc dir d} { if {file type()!=CHAR FILE) fstream: :seelcg{ofs,d) ; return *this; int loclc{ int lck type, off t len, int cmd=F SETLK} { if (file type(}!=CHAR FILE) return Ц regfile::lock{lck type,len,cmd}; /else return -1; )! int lockw{ ;et lck type, ,off t len) { j.if (file type{) !=CHAR FIL.E} return . regfile: Mockw(lck type, len) ; else return -1; int unlock! off t len) { if {file type(}!=CHAR FILE} return regfile::unlock(len); else return -1; int getlock,( int lck type, off t len, struct flocks flck) { if {file type() !=CHAR F1LE} return regfile::getlock{lck type,len,flck); else return -1; /* devfile.h */ Функция devfiler.create создает файл устройства с помощью API mknod. Аргумент type показывает, какой файл устройства должен быть создан - байт-ориентированный {type=c) или блок-ориентированный {type=b). Старший и младший номера устройства, права доступа и имя файла устройства задаются аргументами majorno, minor no, prot и fn. Функция devfile ::create возвращает значение, равное возвращаемому значению API mknod. Созданный файл устройства можно открывать, читать, записывать в него данные, закрывать его подобно обычному файлу. Таким образом, devfile наследует все функции fstream, необходимые для информационного доступа к объектам. При этом гфоизвольная выборка данных из байт-ориентированных файлов устройств не допускается. Следовательно, функции devfile::tellg и devfiler.seekg работают только с блок-ориентированными файлами устройств. Ниже приведена программа testjdevfile. С, создающая байт-ориентированный файл устройства, который имеет имя /dev/tty, а также старший и младший номера, соответственно равные 30 и 15. Затем программа открывает этот файл для записи данных и закрывает его. ♦include devfile.h int mainO { открыть файл устройства для записи devfile ndev( /dev/tty , ios::out, 0755); ndev This is a sample output stringXn ; записать данные в файл ndev .-close О ; закрыть файл устройства return 0; ) 7.12. Класс symfile для символических ссылок Объект типа символическая ссылка отличается от объекта класса filebase способом создания. Кроме того, имеется новая функция-член ref path, которая описывает путевое имя файла, являющегося объектом-символиче-ской ссылкой. Определенный ниже класс symfile инкапсулирует все свойства символических ссылок UNIX ♦ifndef SYMFILE H /* This is symfile.h header */ ♦define SYMFILE H ♦include filebase.h /* A class to encapsulate UNIX symbolic link file objects properties */ class symfile : public filebase { public: symfile0 {}; symfile(const char* fn, int flags, int prot) : filebase(fn,flags,prot) {;}; void open( int mode ) { fstream::open{ filename, mode ); } int setlink( const char* old link, const char* new link} { filename = new char[strlen(newslink)+1]; strcpy(filename,new link}; return symlink(old link,new link}; const char* ref path() { static char xbuf[256]; if (readlink(filename, xbuf, 256)) return xbuf; else return (char*)-l; };
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |