The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Документация для Linux" / Оглавление документа
next up previous contents index
Next: Операции над очередями сообщений Up: Управление очередями сообщений Previous: Использование msgctl   Contents   Index

Программа-пример

Назначение переменных, описанных в программе:

command

Код управляющего действия.

choice

Используется для выбора поля ассоциированной структуры данных, которое нужно изменить.

msqid_ds

Структура для хранения информации об очереди.

Программа ведет себя следующим образом. Прежде всего предлагается ввести допустимый идентификатор очереди сообщений, который заносится в переменную msqid (строки 15, 16). Это значение требуется в каждом системном вызове msgctl.

Затем нужно ввести код выбранного управляющего действия (строки 17-22); он заносится в переменную command.

Если выбрано действие IPC_STAT (код 1), системный вызов выполняется (строка 31) и распечатывается информация о состоянии очереди (строки 32-39); в программе распечатываются только те поля структуры, которые могут быть переустановлены. Отметим, что если системный вызов завершается неудачей, распечатывается информация о состоянии очереди на момент последнего успешного выполнения системного вызова. Кроме того, выводится сообщение об ошибке и распечатывается значение переменной errno (строки 90, 91). Если системный вызов завершается успешно, выводится сообщение, уведомляющее об этом, и значение использованного идентификатора очереди сообщений (строки 95, 96).

Если выбрано действие IPC_SET (код 2), программа прежде всего получает информацию о текущем состоянии очереди сообщений с заданным идентификатором (строка 45). Это необходимо, поскольку пример обеспечивает изменение только одного поля за один раз, в то время как системный вызов изменяет всю структуру целиком. Кроме того, если в одно из полей структуры, находящейся в об- ласти памяти пользователя, будет занесено некорректное значение, это может вызвать неудачи в выполнении управляющих действий, повторяющиеся до тех пор, пока значение поля не будет исправлено. Затем программа предлагает ввести код, соответствующий полю структуры, которое должно быть изменено (строки 46-53). Этот код заносится в переменную choice. Далее, в зависимости от указанного поля, программа предлагает ввести то или иное новое значение (строки 54-79). Значение заносится в соответствующее поле структуры данных, расположенной в области памяти пользователя, и выполняется системный вызов (строка 81).

Если выбрано действие IPC_RMID (код 3), выполняется системный вызов (строка 86), удаляющий из системы идентификатор msqid, очередь сообщений и ассоциированную с ней структуру данных. Отметим, что для выполнения этого управляющего действия аргумент buf не требуется, поэтому его значение может быть заменено нулем (NULL).

      1 /* Программа иллюстрирует
      2    возможности системного вызова msgctl()
      3    (управление очередями сообщений) */

      4 #include <stdio.h>
      5 #include <sys/types.h>
      6 #include <sys/ipc.h>
      7 #include <sys/msg.h>

      8 main ()
      9 {
     10   extern int errno;
     11   int msqid, command, choice, rtrn;
     12   struct msqid_ds msqid_ds, *buf;
     13   buf = &msqid_ds;

     14   /* Ввести идентификатор и действие */
     15   printf ("Введите идентификатор msqid: ");
     16   scanf ("%d", &msqid);

     17   printf ("Введите номер требуемого действия:\n");
     18   printf ("  IPC_STAT = 1\n");
     19   printf ("  IPC_SET  = 2\n");
     20   printf ("  IPC_RMID = 3\n");
     21   printf ("  Выбор    = ");
     22   scanf ("%d", &command);

     23   /* Проверить значения */
     24   printf ("идентификатор = %d, действие = %d\n",
     25           msqid, command);

     26   switch (command) {
     27     case 1: /* Скопировать информацию
     28                о состоянии очереди сообщений
     29                в пользовательскую структуру
     30                и вывести ее */
     31       rtrn = msgctl (msqid, IPC_STAT, buf);
     32       printf ("\n Идентификатор пользователя = %d\n",
     33               buf->msg_perm.uid);
     34       printf ("\n Идентификатор группы = %d\n",
     35               buf->msg_perm.gid);
     36       printf ("\n Права на операции = 0%o\n",
     37               buf->msg_perm.mode);
     38       printf ("\n Размер очереди в байтах = %d\n",
     39               buf->msg_qbytes);
     40       break;

     41     case 2: /* Выбрать и изменить поле (поля)
     42                 ассоциированной структуры данных */
     43       /* Сначала получить исходное значение
     44          структуры данных */
     45       rtrn = msgctl (msqid, IPC_STAT, buf);
     46       printf ("\nВведите номер поля, ");
     47       printf ("которое нужно изменить:\n");
     48       printf ("  msg_perm.uid  = 1\n");
     49       printf ("  msg_perm.gid  = 2\n");
     50       printf ("  msg_perm.mode = 3\n");
     51       printf ("  msg_qbytes    = 4\n");
     52       printf ("  Выбор         = ");
     53       scanf ("%d", &choice);

     54       switch (choice) {
     55         case 1:
     56           printf ("\nВведите ид-р пользователя: ");
     57           scanf ("%d", &buf->msg_perm.uid);
     58           printf ("\nИд-р пользователя = %d\n",
     59                   buf->msg_perm.uid);
     60           break;
     61         case 2:
     62           printf ("\nВведите ид-р группы: ");
     63           scanf ("%d", &buf->msg_perm.gid);
     64           printf ("\nИд-р группы = %d\n",
     65                   buf->msg_perm.uid);
     66           break;

     67         case 3:
     68           printf ("\nВведите восьмеричный код прав: ");
     69           scanf ("%o", &buf->msg_perm.mode);
     70           printf ("\nПрава на операции = 0%o\n",
     71                   buf->msg_perm.mode);
     72           break;

     73         case 4:
     74           printf ("\nВведите размер очереди = ");
     75           scanf ("%d", &buf->msg_qbytes);
     76           printf ("\nЧисло байт в очереди = %d\n",
     77                   buf->msg_qbytes);
     78           break;
     79       }

     80       /* Внести изменения */
     81       rtrn = msgctl (msqid, IPC_SET, buf);
     82       break;

     83    case 3: /* Удалить идентификатор и
     84               ассоциированные с ним очередь
     85               сообщений и структуру данных */
     86      rtrn = msgctl (msqid, IPC_RMID, NULL);
     87   }

     88   if (rtrn == -1) {
     89     /* Сообщить о неудачном завершении */
     90     printf ("\nmsgctl завершился неудачей!\n");
     91     printf ("\nКод ошибки = %d\n", errno);
     92   }

     93   else {
     94     /* При успешном завершении сообщить msqid */
     95     printf ("\nmsgctl завершился успешно,\n");
     96     printf ("идентификатор = %d\n", msqid);
     97   }

     98   exit (0);
     99 }



Alex Otwagin 2002-12-16



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру