Переменная mqid должна быть допустимым
uses ipc;
Function msgctl(mqid:longint; cmd:longint; msg_stat:PMSQid_ds): Boolean;
Переменная mqid должна быть допустимым идентификатором очереди. Пропуская пока параметр cmd, обратимся к третьему параметру msg_stat, который содержит адрес структуры TMSQid_ds. Эта структура определяется в файле ipc и содержит следующие элементы:
PMSQid_ds = ^TMSQid_ds;
TMSQid_ds = record
msg_perm : TIPC_perm; (* Владелец/права доступа *)
msg_first : PMsg;
msg_last : PMsg;
msg_stime : Longint; (* Время посл. вызова msgsnd *)
msg_rtime : Longint; (* Время посл. вызова msgrcv *)
msg_ctime : Longint; (* Время посл. изменения *)
wwait : Pointer;
rwait : pointer;
msg_cbytes : word;
msg_qnum : word; (* Число сообщений в очереди *)
msg_qbytes : word; (* Макс. число байтов в очереди *)
msg_lspid : word; (* Идентификатор процесса,
последним вызвавшего msgsnd *)
msg_lrpid : word; (* Идентификатор процесса,
последним вызвавшего msgrcv *)
end;
Структура TIPC_perm, с которой уже встречались ранее, содержит связанную с очередью информацию о владельце и правах доступа. Переменные msg_stime, msg_rtime, msg_ctime содержат число секунд, прошедшее с 00:00 по гринвичскому времени 1 января 1970 г. (Следующий пример покажет, как можно преобразовать такие значения в удобочитаемый формат.)
Параметр cmd в вызове msgctl сообщает системе, какую операцию она должна выполнить. Существуют три возможных значения этого параметра, каждое из которых может быть применено к одному из трех средств межпроцессного взаимодействия. Они обозначаются следующими константами, определенными в файле ipc.
IPC_STAT |
Сообщает системе, что нужно поместить информацию о статусе объекта в структуру msg_stat |
IPC_SET |
Используется для задания значений управляющих параметров очереди сообщений, содержащихся в структуре msg_stat. При этом могут быть изменены только следующие поля: msq_stat.msg_perm.uid msq_stat.msg_perm.gid msq_stat.msg_perm.mode msq_stat.msg_qbytes Операция IPC_SET завершится успехом только в случае ее выполнения суперпользователем или текущим владельцем очереди, заданным параметром msq_stat.msg_perm.uid. Кроме того, только суперпользователь может увеличивать значение msg_qbytes – максимальное количество байтов, которое может находиться в очереди |
IPC_RMID |
Эта операция удаляет очередь сообщений из системы. Она также может быть выполнена только суперпользователем или владельцем очереди. Если параметр command принимает значение IPC_RMID, to параметр msg_stat задается равным nil |
Следующий пример, программа show_msg, выводит часть информации о статусе объекта очереди сообщений. Программа должна вызываться так:
$ show_msg значение_ключа
Программа show_msg использует библиотечную процедуру ctime для преобразования значений структуры time_t в привычную запись. (Процедура ctime и другие функции для работы с временными значениями будут обсуждаться в главе 12.) Текст программы show_msg:
(* Программа showmsg - выводит данные об очереди сообщений *)
{$mode objfpc}
uses ipc,stdio,sysutils;
procedure mqstat_print(mkey:tkey; msq_id:longint; mstat:pmsqid_ds);
begin
writeln (#$a'Ключ ', mkey, ', msg_qid ', msq_id, #$a);
writeln(mstat^.msg_qnum, ' сообщений в очереди'#$a);
writeln('Последнее сообщение послано процессом ', mstat^.msg_lspid, ' в ',
ctime(mstat^.msg_stime));
writeln('Последнее сообщение принято процессом ', mstat^.msg_lrpid, ' в ',
ctime(mstat^.msg_rtime));
end;
var
mkey:tkey;
msq_id:longint;
msq_status:tmsqid_ds;
begin
if paramcount<>1 then
begin
writeln(stderr, 'Применение: showmsg значение_ключа');
halt(1);
end;
(* Получаем идентификатор очереди сообщений *)
try
mkey:=tkey(strtoint(paramstr(1)));
except
on e:econverterror do
begin
writeln(stderr, 'Нечисловой идентификатор очереди сообщений');
halt (2);
end;
end;
msq_id := msgget(mkey, 0);
if msq_id = -1 then
begin
perror('Ошибка вызова msgget');
halt(2);
end;
(* Получаем информацию о статусе *)
if not msgctl(msq_id, IPC_STAT, @msq_status) then
begin
perror('Ошибка вызова msgctl');
halt(3);
end;
(* Выводим информацию о статусе *)
mqstat_print(mkey, msq_id, @msq_status);
halt(0);
end.
Упражнение 8.4. Измените процедуру show_msg так, чтобы она выводила информацию о владельце и правах доступа очереди сообщений.
Упражнение 8.5. Взяв за основу программу chmod, напишите программу msg_chmod, которая изменяет связанные с очередью права доступа. Очередь сообщений также должна указываться значением ее ключа.