Для того чтобы отправить или получить сообщения, вызывающий процесс
создает структуру по такой общей форме:
struct msgbuf { longmtype;
/* тип сообщения, должен быть > 0 */
charmtext[1];
/* содержание сообщения */
};
Поле
mtext
является массивом (или другой структурой), размер которого определяется
msgsz,
неотрицательным целым значением.
Сообщения нулевой длины (т.е. без поля
mtext)
разрешены.
Поле
mtype
должно принимать только положительные целые значения,
используемые процессом-получателем для выбора сообщений
(см. раздел, касающийся
msgrcv).
Вызывающий процесс должен иметь права на запись для отправки данных,
а при получении - права на чтение для этой очереди.
Системный вызов
msgsnd
добавляет сообщение, указанное параметром
msgp,
в очередь сообщений, идентификатор которой указывается параметром
msqid.
Если для очереди доступно достаточно места, то
msgsnd
немедленно сообщает о нормальном завершении работы.
(Емкость очереди определяется полем
msg_bytes
в ассоциированной структуре данных для очереди сообщений.
Во время создания очереди это поле инициализируется в
MSGMNB
байтов, но это ограничение может быть изменено, используя
msgctl.)
Если для очереди недостаточно пространства, то поведением
по умолчанию для
msgsnd
будет блокировка, до тех пор, пока не станет достаточно места.
Если
IPC_NOWAIT
установлено в
msgflg
то вызов вместо этого выдаст ошибку
EAGAIN.
Заблокированный вызов
msgsnd
также может выдать ошибку, если очередь удалена
(в этом случае системный вызов выдаст ошибку, определив
errno
в значение
EAGAIN.
(msgsnd и msgrcv
никогда автоматически не перезапускаются после прерывания
обработчиком сигнала, нещависимо от установки флага
SA_RESTART
при установки обработчика сигнала.)
До успешного завершения очереди сообщений структура данных
будет обновляться таким образом:
msg_lspid
будет установлено равным идентификатору вызывающего процесса.
Значение
msg_qnum
будет увеличено на 1.
msg_stime
будет установлено равным текущему времени.
Системный вызов
msgrcv
записывает сообщение из очереди (идентификатор
которой указан в
msqid)
в буфер
msgbuf
(находящийся в
msgp),
удаляя сообщение из очереди.
Параметр
msgsz
задает максимальный размер элемента
mtext
структуры, находящейся по адресу, указанному в аргументе
msgp.
Если длина текста сообщения больше, чем
msgsz,
и флаг
msgflg
установлен в
MSG_NOERROR,
то текст сообщения будет урезан (а урезанная часть потеряна),
иначе сообщение не удаляется из очереди, а системный вызов
возвращает ошибку, установив значение
errno,
равное
E2BIG.
Параметр
msgtyp
задает тип сообщения следующим образом:
если
msgtyp
равен
нулю,
то используется первое сообщение из очереди;
если
msgtyp
больше
нуля,
то из очереди берется первое сообщение типа
msgtyp
(если только во флаге
msgflg
нет бита
MSG_EXCEPT.
В этом случае из очереди берется первое
сообщение, тип которого не равен
msgtyp).
Если
msgtyp
меньше
нуля,
то из очереди берется первое сообщение со
значением, меньшим, чем абсолютное значение
msgtyp.
Параметр
msgflg
состоит из комбинации следующих флагов:
IPC_NOWAIT,
который указывает на немедленный возврат из функции, если в очереди нет
сообщений необходимого типа. При этом системный вызов возвращает ошибку,
устанавливая значение
errno
равным
ENOMSG;
MSG_EXCEPT
, который используется (если
msgtyp
больше, чем
0)
для чтения первого сообщения, тип которого не равен
msgtyp;
MSG_NOERROR,
используемый для урезания текста сообщения, размер которого больше
msgsz
байтов.
Если в очереди нет сообщения необходимого типа, и в
msgflg
не установлен флаг
IPC_NOWAIT,
то вызывающий процесс будет заблокирован до тех пор, пока не произойдет
одно из следующих событий:
сообщение необходимого типа помещено в очередь;
очередь сообщений удалена из системы
(в этом случае системный вызов возвращает ошибку,
устанавливая значение
errno ,
равное
EIDRM).
Вызывающий процесс получает сигнал, который он должен
обработать. В этом случае системный вызов возвращает ошибку,
устанавливая значение переменной
errno ,
равное
EINTR.
При удачном завершении операции структура данных очереди
сообщений будет обновлена следующим образом:
значение
msg_lrpid
будет обозначать идентификатор вызывающего процесса;
msg_qnum
уменьшается на 1;
значение
msg_rtime
будет равно значению текущего времени.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
При ошибке обе функции возвращают
-1,
а переменная
errno
приобретает соответствующее значение.
В противном случае
msgsnd
возвращает
0,
а
msgrvc
возвращает количество байтов, скопированных в массив
mtext.
НАЙДЕННЫЕ ОШИБКИ
Значения
errno,
устанавливаемые при выполнении функции
msgsnd:
EAGAIN
Сообщение не может быть помещено в очередь,
потому что размер очереди превысит лимит, равный
msg_qbytes
, а в параметре
mgsflg
установлен флаг
IPC_NOWAIT.
EACCES
Вызывающий процесс не имеет прав записи в очередь.
EFAULT
Память с адресом, указанным
msgp,
недоступна.
EIDRM
Очередь сообщений была удалена из системы.
EINTR
Процесс ждал свободного места в очереди и получил
сигнал, который он должен обработать.
EINVAL
Задано неправильное значение
msqid,
неположительное значение
mtype
или неправильное значение
msgsz
(меньшее, чем 0, или большее, чем системный лимит, заданный
MSGMAX).
ENOMEM
В системе недостаточно памяти для копирования содержимого буфера
msgbuf.
Значения
errno,
устанавливаемые при выполнении функции
msgrcv:
E2BIG
Длина текста получаемого сообщения больше, чем
msgsz,
а в поле
msgflg
не установлен флаг
MSG_NOERROR.
EACCES
Вызывающий процесс не имеет прав на чтение очереди сообщений.
EFAULT
Память с адресом, указанным
msgp,
недоступна.
EIDRM
Процесс ждал появления сообщения в очереди,
и в это время она была удалена.
EINTR
Процесс ждал появления сообщения в очереди
и получил сигнал, который должен обработать.
EINVAL
Задано неправильное значение
msqid,
или значение
msgsz
меньше, чем
0.
ENOMSG
В очереди нет сообщения необходимого типа, а в параметре
msgflg
установлен флаг
IPC_NOWAIT.
ЗАМЕЧАНИЯ
На работу системного вызова
msgsnd
влияют следующие системные лимиты:
MSGMAX
Максимальный размер текста сообщения: по умолчанию
он равен 8192 байтам.
MSGMNB
Максимальный размер очереди сообщений: 18384 байтов.
Суперпользователь может устанавливать больший размер очереди сообщений,
чем
MSGMNB,
при помощи системного вызова
msgctl.
В принципе, нет существенных ограничений в количестве
заголовков сообщений
(MSGTQL)
и в размере пула сообщений
(MSGPOOL).
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID.
ЗАМЕЧАНИЯ
Аргумент-указатель обозначен как struct msgbuf * в
libc4, libc5, glibc 2.0, glibc 2.1. В glibc 2.2, в соответствии
с SUSv2, он обозначен как void *.