Если указанное полное имя не существует или недоступно вызывающему процессу, ftok возвращает значение –1. Помните, что файл, имя которого используется для вычисления ключа, не должен быть одним из тех, которые создаются и удаляются сервером в процессе работы, поскольку каждый раз при создании заново эти файлы получают, вообще говоря, другой номер узла, а это может изменить ключ, возвращаемый функцией ftok при очередном вызове.
Пример
Программа в листинге 3.1 принимает полное имя в качестве аргумента командной строки, вызывает функции stat и ftok, затем выводит значения полей st_dev и st_ino структуры stat и получающийся ключ IPC. Эти три значения выводятся в шестнадцатеричном формате, поэтому легко видеть, как именно ключ IPC формируется из этих двух значений и идентификатора 0x57.
//svipc/ftok.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 struct stat stat;
6 if (argc != 2)
7 err_quit("usage: ftok
8 Stat(argv[1], &stat);
9 printf("st_dev: &lx, st_ino: %Ix, key: %x\n",
10 (u_long) stat.st_dev, (u_long) stat.st_ino,
11 Ftok(argv[1], 0x57));
12 exit(0);
13 }
Выполнение этой программы в системе Solaris 2.6 приведет к следующим результатам:
solaris %ftok /etc/system
st_dev: 800018, st_ino: 4a1b, key: 57018a1b
solaris %ftok /usr/tmp
st_dev: 800015, st_ino: 10b78, key: 57015b78
solaris %ftok /home/rstevens/Mail.out
st_dev: 80001f, st_ino: 3b03, key: 5702fb03
Очевидно, идентификатор определяет старшие 8 бит ключа; младшие 12 бит st_dev определяют следующие 12 бит ключа, и наконец, младшие 12 бит st_ino определяют младшие 12 бит ключа.
Цель этого примера не в том, чтобы впоследствии рассчитывать на такой способ формирования ключа из перечисленной информации, а в том, чтобы проиллюстрировать алгоритм комбинации полного имени и идентификатора конкретной реализацией. В других реализациях алгоритм может быть другим.
ПРИМЕЧАНИЕ
В FreeBSD используются младшие 8 бит идентификатора, младшие 8 бит st_dev и младшие 16 бит st_ino.
Учтите, что отображение, производимое функцией ftok, — одностороннее, поскольку часть бит st_dev и st_ino не используются. По данному ключу нельзя определить полное имя файла, заданное для вычислений.
3.3. Структура ipc_perm
Для каждого объекта IPC, как для обычного файла, в ядре хранится набор информации, объединенной в структуру.
struct ipc_perm {
uid_t uid; /*идентификатор пользователя владельца*/
gid_t gid; /*идентификатор группы владельца */
uid_t cuid; /*идентификатор пользователя создателя*/
gid_t cgid; /*идентификатор группы создателя*/
mode_t mode; /*разрешения чтения-записи*/
ulong_t seq; /*последовательный номер канала*/
key_t key; /* ключ IPC */
}
Эта структура вместе с другими переименованными константами для функций System V IPC определена в файле
3.4. Создание и открытие каналов IPC
Три функции getXXX, используемые для создания или открытия объектов IPC (табл. 3.1), принимают ключ IPC (типа key_t) в качестве одного из аргументов и возвращают целочисленный идентификатор. Этот идентификатор отличается от того, который передавался функции ftok, как мы вскоре увидим. У приложения есть две возможности задания ключа (первого аргумента функций getXXX):
1. Вызвать ftok, передать ей полное имя и идентификатор.
2. Указать в качестве ключа константу IPCPRIVATE, гарантирующую создание нового уникального объекта IPC.
Последовательность действий иллюстрирует рис. 3.1.
Рис. 3.1. Вычисление идентификаторов IPC по ключам