MSGCTL(2) Руководство программиста Linux MSGCTL(2)

ИМЯ

msgctl - операции для работы с сообщениями System V

ОБЗОР

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

ОПИСАНИЕ

Вызов msgctl() выполняет операцию, заданную в cmd, над очередью сообщений System V с идентификатором msqid.

Структура данных msqid_ds определена в <sys/msg.h> следующим образом:

struct msqid_ds {

    struct ipc_perm msg_perm;     /* владелец и права */

    time_t          msg_stime;    /* время последнего msgsnd(2) */

    time_t          msg_rtime;    /* время последнего msgrcv(2) */

    time_t          msg_ctime;    /* время последнего изменения */

    unsigned long   __msg_cbytes; /* текущее количество байт в

                                     очереди (нет в стандарте) */

    msgqnum_t       msg_qnum;     /* текущее количество сообщений

                                     в очереди */

    msglen_t        msg_qbytes;   /* максимальное количество байт

                                     для очереди */

    pid_t           msg_lspid;    /* PID последнего msgsnd(2) */

    pid_t           msg_lrpid;    /* PID последнего msgrcv(2) */
};

Структура ipc_perm определена следующим образом (значения полей устанавливаются с помощью IPC_SET):

struct ipc_perm {

    key_t          __key;       /* ключ, передаваемый в msgget(2) */

    uid_t          uid;         /* эффективный UID владельца */

    gid_t          gid;         /* эффективный GID владельца */

    uid_t          cuid;        /* эффективный UID создателя */

    gid_t          cgid;        /* эффективный GID создателя */

    unsigned short mode;        /* права */

    unsigned short __seq;       /* порядковый номер */
};

Возможные значения cmd:

Копирует информацию из структуры данных ядра, связанной с msqid, в структуру msqid_ds, расположенную по адресу buf. Вызывающий должен иметь права на чтение очереди сообщений.
Записывает значения некоторых полей структуры msqid_ds, адрес которой указан в buf, в структуру данных ядра, связанную с этой очередью сообщений, обновляя при этом её поле msg_ctime. Обновляются следующие поля структуры: msg_qbytes, msg_perm.uid, msg_perm.gid и msg_perm.mode (младшие 9 бит). Эффективный UID вызывающего процесса должен совпадать с идентификатором владельца (msg_perm.uid) или создателя (msg_perm.cuid) очереди сообщений, или вызывающий должен иметь привилегии. Для указания значения msg_qbytes большего чем значение системного параметра MSGMNB также требуются соответствующие привилегии (Linux: мандат CAP_SYS_RESOURCE).
Немедленно удаляет очередь сообщений, «будя» все процессы, ожидающие записи или чтения этой очереди (при этом возвращается ошибка, а переменная errno приобретает значение EIDRM). Вызывающий процесс должен иметь соответствующие привилегии или его эффективный идентификатор пользователя должен совпадать с идентификатором создателя или владельца очереди сообщений. Третий аргумент msgctl() в этом случае игнорируется.
Возвращает параметры и информацию о системных максимальных значениях очереди сообщений в структуре, указанной в buf. Данная структура имеет тип msginfo (то есть, требуется приведение типов) и определена в <sys/msg.h>, если определён макрос тестирования свойств _GNU_SOURCE:
struct msginfo {

    int msgpool; /* размер в килобайтах буферного пула,

                    используемого для хранения данных сообщения;

                    ядром не используется */

    int msgmap;  /* максимальное количество элементов в карте

                    сообщений; ядром не используется */

    int msgmax;  /* максимальное количество байт, которые могут быть

                    записаны в одно сообщение */

    int msgmnb;  /* максимальное количество байт, которое можно

                    записать в очередь; используется для инициализации

                    msg_qbytes во время создания очереди

                    (msgget(2)) */

    int msgmni;  /* максимальное количество очередей сообщений */

    int msgssz;  /* размер сегмента сообщения;

                    ядром не используется */

    int msgtql;  /* максимальное количество сообщений во всех очередях

                    в системе; ядром не используется */

    unsigned short int msgseg;

                 /* максимальное количество сегментов;

                    ядром не используется */
};
Значения msgmni, msgmax и msgmnb можно изменить с помощью файлов в /proc с теми же именами; подробней смотрите proc(5).
Возвращает структуру msginfo, содержащую такую же информацию что и при операции IPC_INFO, за исключением того, что возвращаемые значения полей содержат информацию о системных ресурсах, потребляемых очередями сообщений: в поле msgpool возвращается количество очередей сообщений, которые в данный момент находятся в системе; в поле msgmap возвращается общее количество сообщений во всех очередях системы; в поле msgtql возвращается общее количество байт во всех сообщениях во всех очередях системы.
Возвращает структуру msqid_ds как в операции IPC_STAT. Однако аргумент msqid является не уникальным идентификатором, а индексом во внутреннем массиве ядра, в котором содержится информации о всех очередях сообщений в системе.
Возвращает структуру msqid_ds как для MSG_STAT. Однако msg_perm.mode не проверяется на доступность чтения для msqid, что означает, что эту операцию может выполнять пользователь (как и любой пользователь, который может прочитать эту же информацию из /proc/sysvipc/msg).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении IPC_STAT, IPC_SET и IPC_RMID возвращается 0. При успешном выполнении операции IPC_INFO или MSG_INFO возвращается индекс самого последнего использованного элемента во внутреннем массиве ядра, в котором записана информация о всех очередях сообщений. (Эта информация может быть использована при повторяющихся операциях MSG_STAT и MSG_STAT_ANY для получения информации о всех очередях системы.) При успешном выполнении операции MSG_STAT или MSG_STAT_ANY возвращается идентификатор очереди, чей индекс был указан в msqid.

В случае ошибки возвращается -1, а в errno записывается значение ошибки.

ОШИБКИ

В случае возникновения ошибки errno может принимать следующие значения:

Значение аргумента cmd равно IPC_STAT или MSG_STAT, но вызывающий процесс не имеет прав на чтение очереди сообщений msqid, и не имеет мандата CAP_IPC_OWNER в пространстве имён пользователя, которое управляет его пространством имён IPC.
Значение аргумента cmd равно IPC_SET или IPC_STAT, но адрес, указанный в buf, недоступен.
Очередь сообщений была удалена.
Неверное значение cmd или msqid. Или: для операции MSG_STAT значение индекса, указанного в msqid, ссылается на слот массива, который в данный момент не используется.
Значение аргумента cmd равно IPC_SET или IPC_RMID, но эффективный пользовательский идентификатор вызывающего процесса не равен идентификатору создателя (msg_perm.cuid) или владельца (msg_perm.uid) очереди сообщений, и вызывающий не имеет прав (Linux: не имеет мандата CAP_SYS_ADMIN).
Была предпринята попытка (IPC_SET) увеличить msg_qbytes и нарушить границы системного параметра MSGMNB, но вызывающий не имеет прав (Linux: не имеет мандата CAP_SYS_RESOURCE).

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008, SVr4.

ЗАМЕЧАНИЯ

Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.

Операции IPC_INFO, MSG_STAT и MSG_INFO используются программой ipcs(1) для получения информации о выделенных ресурсах. В будущем для этого может быть задействован интерфейс файловой системы /proc.

Различные поля в struct msqid_ds, которые имели тип short в Linux 2.2, в Linux 2.4 теперь имеют тип long. Чтобы воспользоваться этим преимуществом достаточно пересобрать программу с glibc-2.1.91 или более новой версией. (Ядро различает старые и новые вызовы по флагу IPC_64 в cmd.)

СМОТРИТЕ ТАКЖЕ

msgget(2), msgrcv(2), msgsnd(2), capabilities(7), mq_overview(7), svipc(7)

2019-03-06 Linux