Структура ядра msgbuf (описана в файле /usr/src/linux/include/linux/msg.h
) является буфером сообщений:
struct msgbuf {
long mtype; /* тип сообщения */
char mtext[1]; /* текст сообщения */
};
Тут все ясно: тип сообщения и само сообщение. Используя тип сообщения, вы можете помещать в одну очередь разные сообщения, а не создавать еще одну очередь. Например, у нас есть два приложения — клиент и сервер. Вы можете использовать для них одну и ту же очередь: сообщения клиента будут с номером 1 (mtype = 1), а сообщения сервера — с номером 0 (mtype = 0).
Ясное дело, что сообщения из одного символа нас не устраивают, поэтому вы можете переопределить структуру msgbuf в своей программе:
struct my_buf {
long mtype;
char mtext[128];
}
Вы также можете добавлять новые поля в эту структуру (но только в своей программе! Код ядра модифицировать не нужно):
struct my_buf {
long mtype;
char mtext[128];
char info[50];
int status;
}
He бойтесь создавать свои структуры: ядру все равно, с какими данными работать, вам нужно учитывать только максимальный размер сообщения, который определен в файле /usr/src/linux/include/linux/msg.h:
#define MSGMAX 4056
4056 байтов — это максимальный размер не ваших данных, а всей структуры. включая тип сообщения. Размер типа long равен 4 байтам.
Сами сообщения хранятся ядром в структуре msg, которая также определена в файле msg.h:
struct msg {
struct msg *msg_next; /* указатель на след. сообщение
в очереди */
long msg_type; /* тип сообщения */
char *msg_spot; /* адрес самого сообщения (текста) */
short msg_ts; /* размер сообщения (текста) */
};
Сообщения хранятся в виде односвязного списка. Первый член структуры msg_next — это указатель на следующее сообщение в очереди. Второй член msg_type — это тип сообщения, такой же, как в структуре msg_buf.
Следующий член структуры — это указатель на начало текста сообщения, а последний член msg_ts — размер текста сообщения.
Каждый тип объекта IPC представляется в ядре определенной структурой. Для очередей сообщений это структура msqid_ds (описана в файле /usr/src/linux/include/linux/msg.h
).
struct msqid_ds {
struct ipc_perm msg_perm; /* информация о правах
доступа */
struct msg *msg_first; /* указатель на первое сообщение
в очереди */
struct msg *msg_last; /* указатель на последнее сообщение
в очереди*/
time_t msg_stime; /* время последнего вызова msgsnd */
time_t msg_rtime; /* время последнего вызова msgrcv */
time_t msg_ctime; /* время последнего изменения */
struct wait_queue *wwait;
struct wait_queue *rwait;
ushort msg_cbytes;
ushort msg_qnum;
ushort msg_qbytes; /* максимальное число байтов на очередь */
ushort msg_lspid; /* pid последнего испустившего msgsnd */
ushort msg_lrpid; /* последний полученный pid */
};
♦ msg_perm
Это структура типа ipc_perm (ipc_perm определена в файле linux/ipc.h
). Данная структура содержит информацию о владельце и правах доступа:
struct ipc_perm {
key_t key;
ushort uid; /* uid и gid владельца */
ushort gid;
ushort cuid; /* uid и gid создателя */
ushort cgid;
ushort mode; /* режим доступа */
ushort seq; /* системное поле. Вас оно не касается. */
};
♦ msg_ftrst
Указатель на первое сообщение в очереди.
♦ msg_last
Указатель на последнее сообщение в очереди.
♦ msg_stime
Время отправки последнего сообщения из очереди,
♦ msg_rtime
Время последнего изъятия сообщения из очереди.
♦ msg_ctime
Время последнего изменения очереди.
♦ wwait и rwait
Указатели в очередь ожидания ядра, которые используются, когда очередь переполнена и процесс вынужден ждать из-за этого.
♦ msg_cbytes
Суммарный объем всех сообщений в очереди.
♦ msg_qnum
Количество сообщений в очереди.
♦ msg_qbytes
Максимальный размер очереди.
♦ msg_lspid
PID процесса, который послал последнее сообщение в очереди.
♦ msg_lrpid
PID процесса, который получил сообщение из очереди.