int shmctl(int shmid, int cmd, struct shmid_ds *buf);
ОПИСАНИЕ
shmctl()
позволяет пользователю получать информацию о разделяемых сегментах памяти,
устанавливать владельца, группу разделяемого сегмента, права на него;
эта функция может также удалить сегмент. Информация о сегменте, которая находится в
shmid, возвращается в структуру shmid_ds :
struct shmid_ds {
struct ipc_perm shm_perm; /* права на выполнение операции */
int shm_segsz; /* размер сегмента (в байтах) */
time_t shm_atime; /* время последнего подключения */
time_t shm_dtime; /* время последнего отключения */
time_t shm_ctime; /* время последнего изменения структуры */
unsigned short shm_cpid; /* идентификатор процесса создателя */
unsigned short shm_lpid; /* идентификатор процесса, подключавшегося последним */
short shm_nattch; /* количество текущих подключений сегмента */
...
};
Выделенные поля в shm_perm могут быть установлены следующим образом:
используется для копирования информации о сегменте в буфер
buf. Пользователь должен иметь права на чтение сегмента read.
IPC_SET
используется для применения пользовательских изменений к содержимому полей uid, gid
или mode в структуре shm_perms.
Используются только младшие 9 битов mode. Поле
shm_ctime
тоже обновляется. Пользователь должен быть владельцем, создателем или суперпользователем
процесса.
IPC_RMID
используется для пометки сегмента как удаленного. Сегмент будет удален после отключения
(например, когда поле
shm_nattch
ассоциированной структуры
shmid_ds
равно нулю). Пользователь должен быть владельцем, создателем или суперпользователем процесса.
Пользователь должен удостовериться, что сегмент удален; иначе
страницы, которые не были удалены, останутся в памяти или в разделе подкачки.
Также процессы с соответствующими привилегиями
могут предотвратить или разрешить подкачку разделяемого
сегмента памяти при помощи следующих команд cmds
(применимо только для Linux):
SHM_LOCK
запретить подкачку разделяемого сегмента памяти. После блокировки
страницы должны находиться в памяти.
SHM_UNLOCK
разрешить подкачку сегмента.
Процессы, которым разрешено использовать
SHM_LOCK
и
SHM_UNLOCK
при запуске их с возможностью
CAP_IPC_LOCK
(обычно выдаваемой только для root) или если их текущий лимит ресурсов
RLIMIT_MEMLOCK
не равен нулю.
Вызовы
IPC_INFO,
SHM_STAT
и
SHM_INFO
используются программой
ipcs(8)
для получения информации о выделенных ресурсах. В будущем
они могут быть по необходимости изменены или вынесены в файловую систему proc.
СИСТЕМНЫЕ ВЫЗОВЫ
fork()
После команды
fork()
дочерние процессы наследуют сегменты разделяемой памяти.
exec()
После команды
exec()
все подключенные сегменты разделяемой памяти отключаются (но не удаляются).
exit()
Если выполнена команда
exit(),
все сегменты разделяемой памяти отключаются (но не удаляются).
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
При удачном выполнении возвращается 0, а при ошибке -1.
НАЙДЕННЫЕ ОШИБКИ
В случае ошибки переменной
errno
присваиваются следующие значения:
EACCES
Она возникает, если запрашивается IPC_STAT , а
shm_perm.modes не дает доступа
msqid
к чтению.
EFAULT
Аргумент
cmd
равен
IPC_SET
или
IPC_STAT,
а адрес, указываемый
buf,
недоступен.
EINVAL
Эта ошибка происходит, если shmid является неверным идентификатором сегмента или cmd
является неправильной командой.
EIDRM
Эта ошибка возвращается, если shmid указывает на удаленный идентификатор.
EPERM
Эта ошибка возвращается, если была произведена попытка выполнить IPC_SET или IPC_RMID,
эффективный идентификатор вызывающего процессы не является идентификатором создателя
(в соответствие с
shm_perm.cuid),
владельца
(в соответствие с
shm_perm.uid)
или суперпользователя.
EOVERFLOW
возвращается если запрашивается IPC_STAT, а значения gid или uid
слишком велики для помещения в структуру, на которую указывает
buf.
ЗАМЕЧАНИЯ
Многие поля в структуре struct msqid_ds Linux 2.2 были короткими,
в версии 2.4 они стали длиннее. Для эффективного применения этого необходима
перекомпиляция версии в glibc-2.1.91 или более позднюю версию. (Ядро различает
старые и новые вызовы по флагу IPC_64 в аргументе
cmd.)
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID. SVr4 описывает условия ошибки EINVAL,
ENOENT, ENOSPC, ENOMEM, EEXIST. Ни в SVr4, ни в SVID не описывается ошибка
EIDRM.