Руководство программиста для Linux


Очереди сообщений - часть 7


Выше вы заметили отсутствие адреса буфера и длины. В этом конкретном случае мы хотели, чтобы вызов прошел неудачно. Однако мы проверили возвращение E2BIG, которое должно показать, существует ли сообщение затребованного типа. Оберточная функция возвращает TRUE в случае успеха, и FALSE - в противном случае. Отметьте также установленный флаг IPC_NOWAIT, который помешает блокировке, о которой мы говорили раньше.

Системный вызов msgсtl()

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

Для осуществления контроля над очередью предназначен системный вызов msgсtl. SYSTEM CALL: msgctl() PROTOTYPE: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf ); RETURNS: 0 в случае успеха -1 в случае неудачи errno = EACCES (нет прав на чтение и cmd есть IPC_STAT) EFAULT (адрес, на который указывает buf, ошибочен для команд IPC_SET и IPC_STAT) EIDRM (очередь была уничтожена во время запроса) EINVAL (ошибочный msqid или msgsz меньше 0) EPERM (IPC_SET- или IPC_RMID-команда была послана процессом, не имеющим прав на запись (в очередь)) NOTES:

Теперь из общих соображений ясно, что прямые манипуляции с внутреностями ядра могут привести к очень занимательным последствиям. К сожалению, по-настоящему весело будет только тому, кто любит вдребезги и с наслаждением крушить подсистему IPC. Однако при использовании msgctl() с некоторыми командами вероятность огорчительных результатов не очень велика. Вот их и рассмотрим.

IPC_STAT

Сохраняет по адресу buf структуру msqid_ds для очереди сообщений.

IPC_SET

Устанавливает значение элемента ipc_perm структуры msqid. Значения выбирает из буфера.

IPC_RMID

Удаляет очередь из ядра.

Вернемся к нашему разговору о внутреннем представлении очереди сообщений: msqid_ds. Ядро держит экземпляр этой структуры для каждой очереди, существующей в системе. IPC_STAT дает возможность заиметь копию такой структуры для испытаний. Посмотрим на оберточную функцию,которая берет эту структуру и размещает копию по указанному адресу. int get_queue_ds( int qid, struct msgqid_ds *qbuf ) { if( msgctl( qid, IPC_STAT, qbuf) == -1 ) { return(-1); } return(0); }




Начало  Назад  Вперед