Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all
名前
shmctl - System V 共有メモリー (shared memory) を制御する
書式
#include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);
説明
shmctl() は、識別子が shmid の System V 共有メモリーセグメントに対して cmd で指示した制御 命令を実行する。 buf 引数は、 shmid_ds 構造体へのポインターである。 この構造体は <sys/shm.h> で以下のように 定義されている struct shmid_ds { struct ipc_perm shm_perm; /* 所有権と許可 */ size_t shm_segsz; /* セグメントのサイズ (バイト) */ time_t shm_atime; /* 最後の付加 (attach) の時刻 */ time_t shm_dtime; /* 最後の分離 (detach) の時刻 */ time_t shm_ctime; /* 作成時刻 / shmctl() による 最後の変更時刻 */ pid_t shm_cpid; /* 作成者 (creator) の PID */ pid_t shm_lpid; /* 最後の shmat(2)/shmdt(2) の PID */ shmatt_t shm_nattch; /* 現在付加されている数 */ ... }; shmid_ds 構造体のフィールドは以下の通りである。 shm_perm This is an ipc_perm structure (see below) that specifies the access permissions on the shared memory segment. shm_segsz 共有メモリーセグメントのサイズ (バイト単位)。 shm_atime Time of the last shmat(2) system call that attached this segment. shm_dtime Time of the last shmdt(2) system call that detached tgis segment. shm_ctime Time of creation of segment or time of the last shmctl() IPC_SET operation. shm_cpid その共有メモリーセグメントを作成したプロセスの ID。 shm_lpid ID of the last process that executed a shmat(2) or shmdt(2) system call on this segment. shm_nattch Number of processes that have this segment attached. ipc_perm 構造体は以下のように定義されている (強調されたフィールドは IPC_SET を使って設定可 能である): struct ipc_perm { key_t __key; /* shmget(2) に与えられるキー */ uid_t uid; /* 所有者の実効 UID */ gid_t gid; /* 所有者の実効 GID */ uid_t cuid; /* 作成者の実効 UID */ gid_t cgid; /* 作成者の実効 GID */ unsigned short mode; /* 許可 + SHM_DEST と SHM_LOCKED フラグ */ unsigned short __seq; /* シーケンス番号 */ }; The least significant 9 bits of the mode field of the ipc_perm structure define the access permissions for the shared memory segment. The permission bits are as follows: 0400 Read by user 0200 Write by user 0040 Read by group 0020 Write by group 0004 Read by others 0002 Write by others Bits 0100, 0010, and 0001 (the execute bits) are unused by the system. (It is not necessary to have execute permission on a segment in order to perform a shmat(2) call with the SHM_EXEC flag.) cmd として有効な値は以下の通り: IPC_STAT shmid に関連づけられたカーネルデータ構造体の情報を buf で指された shmid_ds 構造体に コピーする。 呼び出し元は共有メモリーセグメントに対する 読み込み許可を持たなければ ならない。 IPC_SET Write the values of some members of the shmid_ds structure pointed to by buf to the kernel data structure associated with this shared memory segment, updating also its shm_ctime member. 以下のフィールドが更新される: shm_perm.uid, shm_perm.gid および shm_perm.mode (の下 位 9 ビット)。 The effective UID of the calling process must match the owner (shm_perm.uid) or creator (shm_perm.cuid) of the shared memory segment, or the caller must be privileged. IPC_RMID セグメントに破棄済みのマークを付ける。 セグメントは、実際には最後プロセスがセグメン トを分離した (関連する shmid_ds 構造体の shm_nattch メンバーが 0 になった) 後でのみ 破棄される。 呼び出し元はそのセグメントの所有者か作成者であるか、特権を持たなければ ならない。 buf 引数は無視される。 セグメントに破棄のマークが付けられると、 関連するデータ構造体において shm_perm.mode フィールドの (標準ではない) SHM_DEST フラグが設定される。 このデータ構造体は IPC_STAT で取得される。 呼び出し元は最終的にはセグメントを忘れずに破棄しなければならない。 そうでなれ ば、フォールト (fault) されたページは メモリーかスワップ (swap) に残り続ける。 proc(5) の /proc/sys/kernel/shm_rmid_forced の説明も参照のこと。 IPC_INFO (Linux 固有) システム全体での共有メモリーの制限とパラメーターに関する情報を、 buf が指す構造体に 入れて返す。 この構造体は shminfo 型である (そのためキャストが必要である)。 shminfo は _GNU_SOURCE 機能検査マクロが定義された場合に <sys/shm.h> で以下のように定義され る: struct shminfo { unsigned long shmmax; /* 最大セグメントサイズ */ unsigned long shmmin; /* 最小セグメントサイズ。 常に 1 */ unsigned long shmmni; /* 最大セグメント数 */ unsigned long shmseg; /* プロセスが付加できる セグメントの最大数。 カーネル内では未使用 */ unsigned long shmall; /* 共有メモリーの最大ページ数。 システム全体での値 */ }; 設定 shmmni, shmmax, shmall は /proc にある同じ名前のファイル経由で変更可能である。 詳しくは proc(5) を参照。 SHM_INFO (Linux 固有) 共有メモリーが消費しているシステム資源に関する情報を 格納した shm_info 構造体を返 す。 この構造体は、 _GNU_SOURCE 機能検査マクロが定義された場合に <sys/shm.h> で以下 のように定義される: struct shm_info { int used_ids; /* 現在存在するセグメント数 */ unsigned long shm_tot; /* 共有メモリーのページ総数 */ unsigned long shm_rss; /* メモリー上にある (スワップされて いない) 共有メモリーページ数 */ unsigned long shm_swp; /* スワップされている共有メモリー ページ数 */ unsigned long swap_attempts; /* Linux 2.4 以降では未使用 */ unsigned long swap_successes; /* Linux 2.4 以降では未使用 */ }; SHM_STAT (Linux 固有) IPC_STAT と同じく shmid_ds 構造体を返す。 但し、 shmid 引数は、セグメント識別子では なく、システム上の全ての共有メモリー セグメントに関する情報を管理するカーネルの内部 配列へのインデックス である。 SHM_STAT_ANY (Linux-specific, Linux 4.17 以降) Return a shmid_ds structure as for SHM_STAT. However, shm_perm.mode is not checked for read access for shmid, meaning that any user can employ this operation (just as any user may read /proc/sysvipc/shm to obtain the same information). 呼び出し元は、cmd に以下の値を指定することで、共有メモリーセグメントが スワップされること を防止したり、許可したりできる: SHM_LOCK (Linux 固有) 共有メモリーセグメントをスワップすることを防止する。 ロックが有効になった後、呼び出 し元は、 存在することが要求された全てのページをフォールトさせなければならない。 セ グメントがロックされると、 関連するデータ構造体において shm_perm.mode フィールドの (標準的ではない) SHM_LOCKED フラグが設定される。 このデータ構造体は IPC_STAT で取 得される。 SHM_UNLOCK (Linux 固有) セグメントのロックを解除し、スワップアウトすることを可能にする。 2.6.10 より前のカーネルでは、特権プロセスだけが SHM_LOCK と SHM_UNLOCK を利用することがで きた。 2.6.10 以降のカーネルでは、非特権プロセスであっても次の条件を満たせば これらの操作 を利用することができる。その条件とは、プロセスの実効 UID がそのセグメントの所有者もしくは 作成者の UID と一致し、 (SHM_LOCK の場合には) ロックするメモリーの合計が RLIMIT_MEMLOCK リ ソース上限 (setrlimit(2) 参照) の範囲内に入っていることである。
返り値
IPC_INFO と SHM_INFO 操作は、成功すると、全ての共有メモリーセグメントに関する情報を 管理し ているカーネルの内部配列の使用中エントリーのインデックスの うち最大値を返す (この情報 は、システムの全ての共有メモリーセグメントに関する情報を 取得するために、操作 SHM_STAT か SHM_STAT_ANY を繰り返し実行する際に使用できる)。 SHM_STAT 操作は、成功すると、 shmid で指 定されたインデックスを持つ共有メモリーセグメントの識別子を返す。 他の操作は、成功の場合 0 を返す。 エラーの場合は -1 を返し、 errno を適切に設定する。
エラー
EACCES IPC_STAT or SHM_STAT is requested and shm_perm.mode does not allow read access for shmid, and the calling process does not have the CAP_IPC_OWNER capability in the user namespace that governs its IPC namespace. EFAULT cmd 引数に IPC_SET か IPC_STAT が指定されたが buf で指されているアドレスにアクセス できない。 EIDRM shmid が削除 (remove) された識別子 (identifier) を指している。 EINVAL shmid が有効な識別子でないか、 cmd が有効なコマンドでない。 もしくは、操作 SHM_STAT か SHM_STAT_ANY の場合に、 shmid で指定されたインデックス値が現在未使用の配列のス ロットを参照していた。 ENOMEM (2.6.9 以降のカーネルにおいて) SHM_LOCK が指定され、 ロックされる予定のセグメント のサイズ (ロックされる共有メモリーセグメントの合計バイト数) が、 呼び出したプロセス の実ユーザー ID についての制限を超えた。 この制限は RLIMIT_MEMLOCK ソフト資源制限で 定義される (setrlimit(2) を参照)。 EOVERFLOW IPC_STAT が試みられ、GID や UID の値が buf で指示される構造体に格納するには大き過ぎ る。 EPERM IPC_SET か IPC_RMID が試みられ、 呼び出したプロセスの実効ユーザー ID が作成者 (shm_perm.cuid) でも所有者 (shm_perm.uid) でもなく、プロセスが特権を持たない (Linux では CAP_SYS_ADMIN ケーパビリティを持たない)。 または (2.6.9 より前のカーネルで) SHM_LOCK または SHM_UNLOCK が指定されている が、プロセスが特権を持たない (Linux では CAP_IPC_LOCK ケーパビリティを持たない)。 (Linux 2.6.9 以降では、 RLIMIT_MEMLOCK が 0 で呼び出し元が特権を持たない場合に も、このエラーが起こる。)
準拠
POSIX.1-2001, POSIX.1-2008, SVr4.
注意
Linux や POSIX の全てのバージョンでは、 <sys/types.h> と <sys/ipc.h> のインクルードは必要 ない。しかしながら、いくつかの古い実装ではこれらのヘッダーファイルのインクルードが必要であ り、 SVID でもこれらのインクルードをするように記載されている。このような古いシステムへの移 植性を意図したアプリケーションではこれらのファイルをインクルードする必要があるかもしれな い。 IPC_INFO, SHM_STAT, SHM_INFO 操作は、 ipcs(1) プログラムで割り当て済の資源に関する情報を提 供するために 使用されている。将来、これらの操作は変更されたり、 /proc ファイルシステムのイ ンターフェースに移動されるかもしれない。 Linux では、 shmctl(IPC_RMID) を使ってすでに削除マークがつけられている共有メモリーセグメン トを あるプロセスが付加 (attach) (shmat(2)) することを許可している。 この機能は他の UNIX の実装では利用できない。 移植性を考慮したアプリケーションではこれに依存しないようにすべき である。 構造体 shmid_ds 内の多くのフィールドは、 Linux 2.2 では short 型だったが、Linux 2.4 では long 型になった。 この利点を生かすには、glibc-2.1.91 以降の環境下で 再コンパイルすれば十分 である。 カーネルは新しい形式の呼び出しと古い形式の呼び出しを cmd 内の IPC_64 フラグで区別 する。
関連項目
mlock(2), setrlimit(2), shmget(2), shmop(2), capabilities(7), sysvipc(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの 説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。