Локальные сети персональных компьютеров. Работа с сервером Novell NetWare© Александр Фролов, Григорий ФроловТом 9, М.: Диалог-МИФИ, 1993, 168 стр. 5.1. Блокирование файловВ этом разделе мы рассмотрим методы синхронизации работы программ, основанные на блокировании файлов. Принцип блокирования файлов достаточно прост. Например, в MS-DOS, если запущена программа SHARE.EXE, программа, открывая файл, может указать, что этот файл будет использоваться ей монопольно. При попытке открыть этот файл еще раз другая программа получит от соответствующей функции MS-DOS код ошибки. Для открывания файлов из программы, составленной на языке программирования C (или C++), удобно использовать функцию open(): int open(const char *path, int access [, unsigned mode]); Для использования этой функции ваша программа должна содержать следующие две строки: #include <fcntl.h> #include <sys\stat.h> Функция возвращает индекс (handle) открытого файла или -1 в случае ошибки. Параметр path указывает путь к открываемому файлу. Параметр access определяет режим доступа к открываемому файлу. Вы можете использовать символические константы (их можно объединять при помощи логической операции ИЛИ):
Необязательный параметр mode указывается только для вновь создаваемых файлов (в режиме O_CREAT). Он может принимать следующие значения:
Эти значения можно объединять при помощи логической операции ИЛИ. Существует еще одна функция для открытия файлов, аналогичная функции open(), - функция sopen(): int sopen(path, access, shflag, mode); Для использования этой функции в программу необходимо включить следующие строки: #include <fcntl.h> #include <sys\stat.h> #include <share.h> #include <IO.H> Параметры этой функции аналогичны параметрам функции open(). Дополнительный параметр shflag может принимать следующие значения:
Приведенные выше константы нельзя объединять логической операцией ИЛИ, можно указывать только одну константу из списка. Сетевая оболочка Novell NetWare предоставляет более удобные средства для блокирования файлов. Эти средства позволяют блокировать сразу несколько файлов, что может быть необходимо для обновления содержимого сложной базы данных. Для того чтобы заблокировать один или несколько файлов средствами сетевой оболочки, вначале надо образовать группу, состоящую из блокируемых файлов. Для добавления файлов в группу служит функция LogFile(). Удалить файл из группы можно при помощи функции ClearFile(). После того как группа файлов создана, все эти файлы можно одновременно заблокировать при помощи функции LockFileSet(). Файлы можно блокировать и во время добавления их в группу. Функция LogFile() имеет следующий прототип: int LogFile(char *FileName, BYTE LockDirective,WORD Timeout); Параметр FileName задает путь к файлу, который необходимо добавить в группу. Параметр LockDirective определяет, надо ли блокировать файл сразу после его добавления в группу:
Параметр Timeout определяет период времени (в 18-х долях секунды), в течение которого файл-сервер будет ожидать, если файл нельзя заблокировать немедленно. Если для этого параметра задать нулевое значение, ожидание выполняться не будет. Функция возвращает ноль при успешном завершении или код ошибки:
Для удаления файла из группы можно использовать функцию ClearFile(): int ClearFile(char *FileName); Единственный параметр функции указывает путь к файлу, удаляемому из общего списка файлов, предназначенных для блокирования. Функция возвращает нулевое значение или значение 0xFF, если файла с указанным путем нет в списке. Функция ClearFileSet() позволяет разблокировать все файлы группы и удалить группу: void ClearFileSet(void); Прототип функции LockFileSet(), используемой для блокирования группы файлов: int LockFileSet(WORD Timeout); Параметр Timeout используется так же, как и при вызове функции LogFile(). Функция возвращает 0 при успешном завершении или код ошибки:
После того как группа файлов заблокирована, вы можете разблокировать отдельные файлы или всю группу сразу. Для разблокирования отдельных файлов используйте функцию ReleaseFile(): int ReleaseFile(char *FileName); Параметр FileName указывает путь к разблокируемому файлу. Функция возвращает нулевое значение или значение 0xFF, если файла с указанным путем нет в списке. Если вам надо разблокировать сразу все файлы, добавленные в группу, используйте функцию ReleaseFileSet(): void ReleaseFileSet(void); Для добавления файлов в группу вместо функции LogFile() можно использовать функцию EBh прерывания INT 21h:
Для удаления файла из списка вместо функции ClearFile() можно использовать функцию EDh прерывания INT 21h:
Для удаления группы файлов и разблокирования
всех файлов вместо функции ClearFileSet() можно
использовать функцию CFh прерывания INT 21h:
Для блокирования группы файлов вместо функции LockFileSet() можно использовать функцию CBh прерывания INT 21h:
Для разблокирования файла вместо функции ReleaseFile() можно использовать функцию ECh прерывания INT 21h:
Для разблокирования группы файлов вместо функции ReleaseFileSet() можно использовать функцию CDh прерывания INT 21h:
5.1.1. Программа FLOCKПриведем пример программы FLOCK (листинг 21), выполняющей блокирование файлов средствами сетевой оболочки. Вначале программа в цикле запрашивает пути к блокируемым файлам до тех пор, пока оператор вместо имени файла не введет символ "-". Каждый введенный файл добавляется в группу при помощи функции LogFile(). Затем вся группа блокируется функцией LockFileSet(). Далее программа ожидает нажатия на любую клавишу. Попробуйте просмотреть содержимое заблокированных файлов с другой рабочей станции - это у вас не получится. После того как вы нажмете на любую клавишу, программа разблокирует группу файлов при помощи функции ReleaseFileSet() и удалит саму группу, вызывая функцию ClearFileSet(). Файлы, разумеется, не удаляются с диска, удаляется только группа путей к файлам, которая использовалась для блокирования. // =================================================== // Листинг 21. Блокирование файлов // Файл flock\flock.cpp // // (C) A. Frolov, 1993 // =================================================== #include <stdlib.h> #include <stdio.h> #include <string.h> #include <conio.h> #define BYTE unsigned char #define WORD unsigned int extern "C" int GetNetWareShellVersion(char *,char *, char *); extern "C" int LogFile(char *, BYTE, WORD); extern "C" int LockFileSet(WORD); extern "C" void ReleaseFileSet(void); extern "C" void ClearFileSet(void); void main(void) { char MajorVersion=0; char MinorVersion=0; char Revision=0; char FilePath[255]; int ccode; printf("\n*FLOCK* (C) Frolov A., 1993\n"); // Проверяем наличие сетевой оболочки asm push si GetNetWareShellVersion(&MajorVersion, &MinorVersion, &Revision); asm pop si if(MajorVersion == 0) { printf("\nОболочка NetWare не загружена\n"); return; } // Создаем набор файлов, которые будут заблокированы for(;;) { printf("\nВведите путь к файлу или '-':"); gets(FilePath); strupr(FilePath); if(FilePath[0] == '-') break; // Добавляем файл в набор ccode = LogFile(FilePath, 0, 0); if(!ccode) printf("Файл %s добавлен к списку\n", FilePath); else printf("Ошибка при добавлении %02.2X\n", ccode); } // Блокируем набор файлов ccode = LockFileSet(0); if(!ccode) printf("Файлы заблокированы\n"); else printf("Ошибка при блокировании " "файлов %02.2X\n", ccode); printf("Для разблокирования файлов нажмите любую клавишу\n"); getch(); // Разблокируем набор файлов ReleaseFileSet(); // Удаляем набор файлов ClearFileSet(); } |