table of contents
MSGGET(2) | Руководство программиста Linux | MSGGET(2) |
ИМЯ¶
msgget - возвращает идентификатор очереди сообщений
ОБЗОР¶
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key, int msgflg);
ОПИСАНИЕ¶
Системный вызов msgget() возвращает идентификатор очереди сообщений, связанный со значением аргумента key. Он также создаёт новую очередь сообщений, если значение key равно IPC_PRIVATE или если с параметром key не существует ни одной очереди сообщений и в поле msgflg указан флаг IPC_CREAT.
Если в msgflg одновременно заданы IPC_CREAT и IPC_EXCL и с таким key очередь сообщений уже существует, то msgget() завершится с ошибкой и errno будет равно EEXIST (тот же эффект как для комбинации O_CREAT | O_EXCL у open(2)).
При создании права доступа к очереди сообщений определяются младшими битами параметра msgflg. Эти биты прав имеют тот же формат и значение, что и права в аргументе mode у вызова open(2) (право на исполнение не используется).
Если создаётся новая очередь сообщений, то этот системный вызов инициализирует структуру данных msqid_ds (см. msgctl(2)) следующим образом:
- Полям msg_perm.cuid и msg_perm.uid присваивается эффективный идентификатор пользователя вызывающего процесса.
- Полям msg_perm.cgid и msg_perm.gid присваивается эффективный идентификатор группы вызывающего процесса.
- Младшим 9 битам msg_perm.mode присваивается значение младших 9 битов msgflg.
- Значения полей msg_qnum, msg_lspid, msg_lrpid, msg_stime и msg_rtime устанавливаются в 0.
- В поле msg_ctime записывается текущее время.
- В поле msg_qbytes записывается системное ограничение MSGMNB.
Если очередь сообщений уже существует, то проверяются права доступа к ней и не помечена ли она для удаления.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении возвращается идентификатор очереди сообщений (неотрицательное целое), иначе возвращается -1, а переменной errno присваивается номер ошибки.
ОШИБКИ¶
При ошибке errno устанавливается в одно из следующих значений:
- EACCES
- Очередь сообщений для ключа key существует, но вызывающий процесс не имеет прав доступа к ней и не имеет мандата CAP_IPC_OWNER.
- EEXIST
- Очередь сообщений для ключа key существует, но в msgflg заданы флаги IPC_CREAT и IPC_EXCL.
- ENOENT
- Для ключа key не существует очереди сообщений, но в msgflg нет флага IPC_CREAT.
- ENOMEM
- Очередь сообщений необходимо создать, но системе не хватает памяти для хранения новой структуры данных.
- ENOSPC
- Очередь сообщений необходимо создать, но лимит, определяющий количество очередей сообщений (MSGMNI), уже достигнут.
СООТВЕТСТВИЕ СТАНДАРТАМ¶
SVr4, POSIX.1-2001.
ЗАМЕЧАНИЯ¶
Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.
IPC_PRIVATE является не полем с флагами, а имеет тип key_t. Если при работе с key используется это специальное значение, то системный вызов игнорирует всё, кроме 9-ти младших битов в msgflg и создаёт новую очередь сообщений (если это возможно).
На вызов msgget() влияет системное ограничение по очередям сообщений:
- MSGMNI
- Максимальное количество очередей сообщений в системе: зависит от политики (в Linux это ограничение можно получить и изменить через /proc/sys/kernel/msgmni).
Замечания, касающиеся Linux¶
В Linux до версии 2.3.20 вызов msgget() возвращал значение EIDRM, если очередь сообщений была запланирована к удалению.
ДЕФЕКТЫ¶
Имя IPC_PRIVATE, возможно, было выбрано неудачно, IPC_NEW отражает смысл действия более ясно.
СМОТРИТЕ ТАКЖЕ¶
msgctl(2), msgrcv(2), msgsnd(2), ftok(3), capabilities(7), mq_overview(7), svipc(7)
2012-05-31 | Linux |