Ядро Linux (2.6) реализации две очереди сообщений:
(довольно 'списки сообщений', поскольку реализация сделана при помощи связанного списка не строго после принципа FIFO),
System V сообщения IPC
Очередь сообщений от System V.
Процесс может вызвать msgsnd()
отправить сообщение. Он должен передать идентификатор IPC очереди сообщений получения, размер сообщения и структуры сообщения, включая тип сообщения и текст.
С другой стороны процесс вызывает msgrcv()
получить сообщение, передавая идентификатор IPC очереди сообщений, где сообщение должно храниться, размер и значение t.
t указывает сообщение, возвращенное из очереди, положительное значение означает, что первое сообщение с его типом, равным t, возвращается, отрицательная величина возвращает последнее сообщение, равное типу t, и нуль возвращает первое сообщение очереди.
Те функции определены в include/linux/msg.h и реализованы в ipc/msg.c
Существуют ограничения на размер сообщения (макс.), общего количества сообщений (mni) и общего размера всех сообщений в очереди (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
Вывод выше от системы Ubuntu 10.10, значения по умолчанию определяются в message.h.
Более невероятно старый материал очереди сообщений System V объяснен здесь.
Очередь сообщений POSIX
Стандарт POSIX определяет механизм очереди сообщений на основе очереди сообщений IPC System V, расширяя его некоторыми техническими возможностями:
См. ipc/mqueue.c
Пример
util-linux
предоставляет некоторые программы для анализа и изменения очередей сообщений, и спецификация POSIX дает некоторые примеры C:
Создайте очередь сообщений с ipcmk
; обычно Вы делали бы это путем вызывания C функций как ftok()
и msgget()
:
$ ipcmk -Q
Позволяет видят то, что произошло при помощи ipcs
или с a cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Теперь заполните очередь некоторыми сообщениями:
$ cat <msg_send.c
#include
#include
int main() {
int msqid = 65536;
struct message {
long type;
char text[20];
} msg;
msg.type = 1;
strcpy(msg.text, "This is message 1");
msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);
strcpy(msg.text, "This is message 2");
msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);
return 0;
}
EOF
Снова, Вы обычно не делаете hardcode msqid в коде.
$ gcc -o msg_send msg_send.c
$ ./msg_send
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 40 2
И другая сторона, которая будет получать сообщения:
$ cat <msg_recv.c
#include
#include
int main() {
int msqid = 65536;
struct message {
long type;
char text[20];
} msg;
long msgtyp = 0;
msgrcv(msqid, (void *) &msg, sizeof(msg.text), msgtyp, MSG_NOERROR | IPC_NOWAIT);
printf("%s \n", msg.text);
return 0;
}
EOF
Посмотрите то, что происходит:
$ gcc -o msg_recv msg_recv.c
$ ./msg_recv
This is message 1
$ ./msg_recv
This is message 2
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
После два получает, очередь пуста снова.
Удалите его впоследствии путем определения ключа (-Q
) или msqid (-q
):
$ ipcrm -q 65536
Если бы это не был сценарий удара, а регулярное применение, то Вы дали бы владение его, чтобы базироваться и установить setuid, обдумал приложение. Затем после выполнения, эффективный пользователь, под которым работает приложение, является корнем. Из-за проблем безопасности однако это находится во многих системах, запрещенных для сценариев оболочки. Этот вопрос здесь на unix.stackexchange.com действительно обрабатывает пути, как преодолеть это.
Используйте sudo. Если Вы не хотите должными быть звонить sudo /path/to/myscript
, запишите короткую обертку exec sudo /path/to/myscript "$@"
. Посмотрите Позволяют setuid на сценариях оболочки, особенно ответе Maciej Piechotka при использовании sudo и моем более общем обсуждении setuid программ.