Вы встречали вызов fcntl в главе 3. У него следующее определение:
#include
int fcntl(int fildes, int command, ...);
Системный вызов fcntlоперирует открытыми дескрипторами файлов и, в зависимости от параметра command, может выполнять разные задачи. Для блокировки файлов интересны три приведенные далее возможные значения параметра command:
□ F_GETLK;
□ F_SETLK;
□ F_SETLKW.
Когда вы используете эти варианты, третий аргумент в вызове должен быть указателем на структуру struct flock, поэтому на самом деле прототип вызова выглядит следующим образом:
int fcntl(int fildes, int command, struct flock *flock_structure);
Структура flock(он англ. file lock ) зависит от конкретной реализации, но, как минимум, она будет содержать следующие элементы:
□ short l_type;
□ short l_whence;
□ off_t l_start;
□ off_t l_len;
□ pid_t l_pid.
Элемент l_typeпринимает одно из нескольких значений (табл. 7.1), определенных в файле fcntl.h.
Таблица 7.1.
| Значение |
Описание |
F_RDLCK |
Разделяемая или совместная блокировка (блокировка на чтение). У разных процессов может быть разделяемая блокировка одних и тех же (или перекрывающихся) участков файла. Если у какого-либо процесса есть разделяемая блокировка, ни один процесс не сможет установить исключительную блокировку этого участка. Для получения совместной блокировки файл должен быть открыт с правом на чтение или на чтение/запись |
F_UNLCK |
Разблокировать. Применяется для снятия блокировок |
F_WRLCK |
Исключительная блокировка (или блокировка на запись). Только один процесс может установить исключительную блокировку на любой конкретный участок файла. После того как процесс установил такую блокировку, никакой другой процесс не сможет установить блокировку любого типа на этот участок файла. Для установки исключительной блокировки файл должен быть открыт с правом на запись или на чтение/запись |
Элементы l_whence, l_startи l_lenопределяют участок файла, непрерывную область в байтах. Элемент l_whenceдолжен задаваться одним из следующих значений: SEEK_SET, SEEK_CUR, SEEK_END(из файла unistd.h). Они соответствуют началу, текущей позиции или концу файла соответственно. Элемент l_whenceзадает смещение для первого байта участка файла, определенного элементом l_start. Обычно оно задается константой SEEK_SET, поэтому l_startотсчитывается от начала файла. Параметр l_lenсодержит количество байтов в участке файла.
Параметр l_pidприменяется для указания процесса, установившего блокировку; см. следующее далее описание значения F_GETLKпараметра command.
Для каждого байта в файле может быть установлена блокировка только одного типа в каждый конкретный момент времени и может быть либо разделяемой блокировкой, либо исключительной или блокировка может отсутствовать. Для системного вызова fcntlсуществует совсем немного комбинаций значений команд и вариантов, поэтому рассмотрим их все по очереди.
Значение F_GETLK параметра command
Первое значение параметра command — F_GETLK. Эта команда получает информацию о файле, который открыт fildes(первый параметр в вызове). Она не пытается блокировать файл. В процессе вызова передаются сведения о типе блокировки, которую хотелось бы установить, и вызов fcntlс командой F_GETLKвозвращает любую информацию, которая могла бы помешать установке блокировки.
Значения, используемые в структуре flock, приведены в табл. 7.2.
Таблица 7.2
| Значение |
Описание |
l_type |
Или F_RDLCKдля разделяемой (только чтение) блокировки, или F_WRLCKдля исключительной (на запись) блокировки |
l_whence |
Одно из значений: SEEK_SET, SEEK_CURили SEEK_END LCK |
l_start |
Начальный байт интересующего вас участка файла |
l_len |
Количество байтов в интересующем вас участке файла |
l_pid |
Идентификатор процесса, удерживающего блокировку |
Процесс может применять вызов с командой F_GETLKдля определения текущего состояния блокировки участка файла. Он должен настроить структуру flock, указав тип требуемой блокировки и определив интересующую его область файла. Вызов fcntlвозвращает в случае успешного завершения значение, отличное от -1. Если у файла уже есть блокировки, препятствующие установке требуемой блокировки, структура flockобновляется соответствующими данными. Если блокировке ничто не мешает, структура flockне изменяется. Если вызов с командой F_GETLKне может получить информацию, он возвращает -1 для обозначения аварийного завершения.
Читать дальше