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


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


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

Что же мы можем делать с полученной копией структуры? Единственное, что можно поменять, это элемент ipc_perm. Это права доступа очереди, информация о создателе и владельце очереди. Однако и отсюда менять позволено только mode, uid и gid.

Давайте напишем оберточную функцию, изменяющую режим доступа очереди. Режим должен быть передан как массив литер (например, "660"). int change_queue_mode( int qid, char *mode ) { struct msqid_ds tmpbuf; /* Берем текущую копию внутренней структуры */ get_queue_ds( qid, &tmpbuf ); /* Применяем уже известный прикол для изменения прав доступа */ sscanf(mode, "%ho", &tmpbuf.msg_perm.mode); /* Модернизируем внутреннюю структуру */ if( msgctl( qid, IPC_SET, &tmpbuf ) == -1 ) { return(-1); } return(0); }

Мы взяли текущую копию внутренней структуры данных посредством вызова нашей get_queue_ds; затем sscanf() меняет элемент mode структуры msg_perm. Однако ничего не произойдет, пока msgctl c IPC_SET не обновил внутреннюю версию.

ОСТОРОЖНО! Изменяя права доступа, можно случайно лишить прав себя самого! Помните, что IPC-объекты не исчезают, пока они не уничтожены должным образом или не перезагружена система. Поэтому то, что вы не видите очереди ipcs-ом, не означает, что ее нет на самом деле.

После того, как сообщение взято из очереди, оно удаляется. Однако, как отмечалось ранее, IPC-объекты остаются в системе до персонального удаления или перезапуска всей системы. Поэтому наша очередь сообщений все еще существует в ядре и пригодна к употреблению в любое время, несмотря на то, что последнее его соообщение уже давно на небесах. Чтобы и душа нашей очереди с миром отошла к богам, нужен вызов msgctl(), использующий команду IPC_RMID: int remove_queue( int qid ) { if( msgctl( qid, IPC_RMID, 0) == -1) { return(-1) } return(0); }




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



Книжный магазин