В данном пункте приводится программа-пример, управляемая посредством меню. Она позволяет поупражняться со всевозможными комбинациями в использовании системного вызова msgget, проследить, как передаются аргументы и получаются результаты.
Имена переменных выбраны максимально близкими к именам, используемым в спецификации синтаксиса системного вызова, что облегчает чтение программы.
Выполнение программы начинается с приглашения ввести шестнадцатеричный ключ key, восьмеричный код прав на операции и, наконец, выбираемую при помощи меню комбинацию флагов (строки 14-30). В меню предлагаются все возможные комбинации, даже бессмысленные, что позволяет при желании проследить за реакцией на ошибку.
Затем выбранные флаги комбинируются с правами на операции, после чего выполняется системный вызов, результат которого помещается в переменную msqid (строка 49). Контроль успешного завершения системного вызова производится в строке 50. Если значение msqid равно -1, выдается сообщение об ошибке и выводится значение внешней переменной errno (строки 52, 53). Если ошибки не произошло, выводится значение полученного идентификатора очереди сообщений (строка 57).
Далее приводится текст программы-примера. Здесь и далее номера
строк служат только для ссылок и не являются частью программы.
1 /* Программа иллюстрирует
2 возможности системного вызова msgget()
3 (получение идентификатора очереди сообщений) */
4 #include <stdio.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/sem.h>
8 #include <errno.h>
9 main ()
10 {
11 key_t key; /* Тип описан как целое */
12 int opperm, flags; /* Права на операции и флаги */
13 int msgflg, msqid;
14 /* Ввести требуемый ключ */
15 printf ("\nВведите шестнадцатеричный ключ: ");
16 scanf ("%x", &key);
17 /* Ввести права на операции */
18 printf ("\nВведите права на операции ");
19 printf ("в восьмеричной записи: ");
20 scanf ("%o", &opperm);
21 /* Установить требуемые флаги */
22 printf ("\nВведите код, соответствущий ");
23 printf ("нужной комбинации флагов:\n");
24 printf (" Нет флагов = 0\n");
25 printf (" IPC_CREAT = 1\n");
26 printf (" IPC_EXCL = 2\n");
27 printf (" IPC_CREAT и IPC_EXCL = 3\n");
28 printf (" Выбор = ");
29 /* Получить флаги, которые нужно установить */
30 scanf ("%d", &flags);
31 /* Проверить значения */
32 printf ("\nключ = 0x%x, права = 0%o, флаги = %d\n",
33 key, opperm, flags);
34 /* Объединить флаги с правами на операции */
35 switch (flags) {
36 case 0: /* Флаги не устанавливать */
37 msgflg = (opperm | 0);
38 break;
39 case 1: /* Установить флаг IPC_CREAT */
40 msgflg = (opperm | IPC_CREAT);
41 break;
42 case 2: /* Установить флаг IPC_EXCL */
43 msgflg = (opperm | IPC_EXCL);
44 break;
45 case 3: /* Установить оба флага */
46 msgflg = (opperm | IPC_CREAT | IPC_EXCL);
47 }
48 /* Выполнить системный вызов msgget */
49 msqid = msgget (key, msgflg);
50 if (msqid == -1) {
51 /* Сообщить о неудачном завершении */
52 printf ("\nmsgget завершился неудачей!\n"
53 printf ("Код ошибки = %d\n", errno);
54 }
55 else
56 /* При успешном завершении сообщить msqid */
57 printf ("\nИдентификатор msqid = %d\n", msqid);
58 exit (0);
59 }