Скачиваний:
85
Добавлен:
12.05.2015
Размер:
913.92 Кб
Скачать

17.2. Ключи типа key_t и функция ftok

В табл. 12.2 было отмечено, что для обращения к объектам System V IPC используются ключи типа key_t. Заголовочный файл <sys/types.h> определяет тип key_t как целое (по меньшей мере 32-разрядное). Значения переменным этого типа обычно присваиваются функцией ftok.

Функция ftok принимает полное имя существующего файла и целочисленный идентификатор, возвращая в качестве результата значение типа key_t (называемое ключом IPC – IPC key):

#include <sys/ipc.h>

key_t ftok (const char *pathname, int id);

/* возвращает ключ IPC либо -1 при возникновении ошибки */

На самом деле функция использует полное имя файла и младшие 8 бит идентификатора для формирования целочисленного ключа IPC.

Эта функция действует в предположении, что для конкретного приложения, использующего IPC, клиент и сервер используют одно и то же полное имя объекта IPC, имеющее какое-то значение в контексте приложения. Это может быть имя демона сервера или имя файла данных, используемого сервером, или имя еще какого-нибудь объекта файловой системы. Если клиенту и серверу для связи требуется только один канал IPC, идентификатору можно присвоить, например, значение 1. Если требуется несколько каналов IPC (например, один от сервера к клиенту и один в обратную сторону), идентификаторы должны иметь разные значения: например, 1 и 2. После того как клиент и сервер договорятся о полном имени и идентификаторе, они оба вызывают функцию ftok для получения одинакового ключа IPC.

Большинство реализаций ftok вызывают функцию stat, а затем объединяют:

  • информацию о файловой системе, к которой относится полное имя pathname(полеst_devструктурыstat);

  • номер узла (i-node) в файловой системе (поле st_inoструктурыstat);

  • младшие 8 бит идентификатора (который не должен равняться нулю).

Из комбинации этих трех значений обычно получается 32-разрядный ключ. Нет никакой гарантии того, что для двух различных путей с одним и тем же идентификатором получатся разные ключи, поскольку количество бит информации в трех перечисленных элементах (идентификатор файловой системы, номер узла, идентификатор IPC) может превышать общее число бит в ключе.

Если указанное полное имя не существует или недоступно вызывающему процессу, ftokвозвращает значение –1. Помните, что файл, имя которого используется для вычисления ключа, не должен быть одним из тех, которые создаются и удаляются сервером в процессе работы, поскольку каждый раз при создании заново эти файлы получают, вообще говоря, другой номер узла, а это может изменить ключ, возвращаемый функциейftokпри очередном вызове.

Пример. Программа влистинге 16.1принимает полное имя файла в качестве аргумента командной строки, вызывает функцииstatиftok, затем выводит значения полейst_devиst_inoструктурыstatи получающийся ключ IPC. Эти три значения выводятся в шестнадцатеричном формате, поэтому легко видеть, как именно формируется ключ IPC из этих двух значений и идентификатора0x57.

Листинг 16.1. Получение и вывод информации о файле и созданном ключе IPC

#include <errno.h>

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(int argc, char **argv)

{

struct stat mystat;

if (argc != 2)

{

fprintf(stderr, "Использование: ftok <полное_имя_файла>\n");

exit(1);

}

if (stat(argv[1], &mystat) == -1)

{

fprintf(stderr, "Ошибка вызова функции stat: %s\n", strerror(errno));

exit(1);

}

printf("st_dev: %lx, st_ino: %lx, key: %x\n",

(unsigned long) mystat.st_dev,

(unsigned long) mystat.st_ino,

ftok(argv[1], 0x57));

exit(0);

}

Выполнение этой программы в ОС Linux дало следующие результаты:

$ ftok /etc/passwd

st_dev: 301, st_ino: 52aa9, key: 57012aa9

$ ftok /tmp

st_dev: 301, st_ino: 177c1, key: 570177c1

$ ftok /home/sergeant/list

st_dev: 305, st_ino: 139d, key: 5705139d

Очевидно, идентификатор определяет старшие 8 бит ключа; далее в ключ заносятся младшие 8 бит st_devи младшие 16 битst_ino.

Цель этого примера в том, чтобы проиллюстрировать алгоритм комбинирования информации о файле и значения идентификатора для вычисления значения ключа IPC, применяемый в ОС Linux. В других реализациях алгоритм может быть другим.

Соседние файлы в папке Chapter.4