Man page - msgop(2)

Packages contains this manual

Available languages:

en fr pl ja ru

Manual

MSGOP

名 前
書 式
説 明
msgsnd()
msgrcv()
返 り 値
エ ラ ー
準 拠
注 意
バ グ

プ ロ グ ラ ム の ソ ー ス
関 連 項 目
こ の 文 書 に つ い て

名 前

msgrcv, msgsnd - System V メ ッ セ ー ジ キ ュ ー 操 作

書 式

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid , const void * msgp , size_t msgsz , int msgflg );

ssize_t msgrcv(int msqid , void * msgp , size_t msgsz , long msgtyp ,
int
msgflg );

説 明

シ ス テ ム コ ー ル msgsnd () と msgrcv () は 、 System V メ ッ セ ー ジ キ ュ ー へ の メ ッ セ ー ジ の 送 信 と 、 メ ッ セ ー ジ の 受 信 に 使 用 さ れ る 。 呼 び 出 し 元 プ ロ セ ス は 、 メ ッ セ ー ジ を 送 信 す る た め に は メ ッ セ ー ジ キ ュ ー に 対 す る 書 き 込 み 許 可 を 、 メ ッ セ ー ジ を 受 信 す る た め に は 読 み 出 し 許 可 を 持 っ て い な け れ ば な ら な い 。

呼 び 出 し 元 プ ロ セ ス は 以 下 に 示 す 構 造 体 を 用 意 し 、 こ の 構 造 体 へ の ポ イ ン タ ー を msgp 引 数 と し て 渡 す 。

struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};

mtext フ ィ ー ル ド は 配 列 (ま た は 他 の 構 造 体 ) で 、 そ の 大 き さ は 非 負 の 整 数 で あ る msgsz で 指 定 さ れ る 。 長 さ 0 の メ ッ セ ー ジ (つ ま り mtext フ ィ ー ル ド が な い メ ッ セ ー ジ ) も 認 め ら れ て い る 。 mtype フ ィ ー ル ド は 厳 密 に 正 の 整 数 で な け れ ば な ら な い 。 こ の 値 は 、 メ ッ セ ー ジ を 受 信 す る プ ロ セ ス で メ ッ セ ー ジ を 選 択 す る た め に 使 用 さ れ る (下 記 の msgrcv () の 説 明 を 参 照 の こ と )。

msgsnd()

msgsnd () シ ス テ ム コ ー ル は msgp 引 数 で 指 定 さ れ た メ ッ セ ー ジ の コ ピ ー を msqid で 指 定 さ れ た 識 別 子 を 持 つ メ ッ セ ー ジ キ ュ ー へ 追 加 す る 。

キ ュ ー に 十 分 な 空 き 容 量 が あ る 場 合 、 msgsnd () は 直 ち に 成 功 す る 。 キ ュ ー の 容 量 は 、 メ ッ セ ー ジ キ ュ ー の デ ー タ 構 造 体 の msg_qbytes フ ィ ー ル ド で 制 御 さ れ る 。 キ ュ ー 作 成 時 に こ の フ ィ ー ル ド は MSGMNB に 初 期 化 さ れ る が 、 こ の 制 限 は msgctl (2) を 使 っ て 変 更 で き る 。 次 の い ず れ か の 条 件 が 成 立 す る 場 合 に 、 メ ッ セ ー ジ キ ュ ー は 一 杯 と 判 断 さ れ る 。

新 し い メ ッ セ ー ジ を そ の キ ュ ー に 追 加 す る と 、 そ の キ ュ ー の 全 バ イ ト 数 が キ ュ ー の 最 大 サ イ ズ ( msg_qbytes フ ィ ー ル ド ) を 超 過 し て し ま う 場 合 。

そ の キ ュ ー に も う 一 つ メ ッ セ ー ジ を 追 加 す る と 、 そ の キ ュ ー が 全 メ ッ セ ー ジ 数 が キ ュ ー の 最 大 サ イ ズ ( msg_qbytes フ ィ ー ル ド ) を 超 過 し て し ま う 場 合 。 こ の チ ェ ッ ク は 、 無 限 個 の 長 さ 0 の メ ッ セ ー ジ を そ の キ ュ ー に 追 加 す る の を 防 ぐ た め に 必 要 で あ る 。 長 さ 0 の メ ッ セ ー ジ は デ ー タ を 含 ま な い が 、 (ロ ッ ク さ れ た ) カ ー ネ ル メ モ リ ー を 消 費 す る か ら で あ る 。

そ の キ ュ ー に 十 分 な 領 域 が な い 場 合 、 デ フ ォ ル ト の 動 作 で は 、 必 要 な 領 域 が で き る ま で msgsnd () は 停 止 (block) す る 。 msgflg IPC_NOWAIT が 指 定 さ れ た 場 合 、 msgsnd () は エ ラ ー EAGAIN で 失 敗 す る 。

停 止 し て い る msgsnd () は 以 下 の 場 合 に も 失 敗 す る 。

キ ュ ー が 削 除 さ れ た 。 こ の 場 合 、 errno EIDRM に 設 定 さ れ る 。

シ グ ナ ル が 捕 捉 さ れ た 。 こ の 場 合 、 errno EINTR に 設 定 さ れ る 。 signal (7) 参 照 。 ( msgsnd () は 、 た と え シ グ ナ ル ハ ン ド ラ ー の 設 定 時 に SA_RESTART を 指 定 し て い た と し て も 、 シ グ ナ ル ハ ン ド ラ ー に よ っ て 割 り 込 ま れ た 後 で 自 動 的 に 再 ス タ ー ト す る こ と は 決 し て な い 。 )

正 常 に 終 了 し た 場 合 、 メ ッ セ ー ジ キ ュ ー の デ ー タ 構 造 体 は 以 下 の よ う に 更 新 さ れ る :

msg_lspid に は 呼 び 出 し 元 プ ロ セ ス の プ ロ セ ス ID が 設 定 さ れ る 。

msg_qnum は 1 増 加 す る 。

msg_stime に は 現 在 時 刻 が 設 定 さ れ る 。

msgrcv()

msgrcv () シ ス テ ム コ ー ル は msqid で 指 定 さ れ た キ ュ ー か ら メ ッ セ ー ジ を 削 除 し 、 msgp で 指 定 さ れ た バ ッ フ ァ ー に そ の メ ッ セ ー ジ を 格 納 す る 。

msgsz 引 数 に は msgp 引 数 で 指 定 さ れ た 構 造 体 の mtext メ ン バ ー の 最 大 の バ イ ト 数 を 指 定 す る 。 メ ッ セ ー ジ の テ キ ス ト の 長 さ が msgsz よ り 大 き い 場 合 の 動 作 は 、 msgflg MSG_NOERROR が 指 定 さ れ て い る か ど う か で 決 ま る 。 MSG_NOERROR が 指 定 さ れ て い れ ば 、 メ ッ セ ー ジ の テ キ ス ト は 切 り 詰 め ら れ る (切 り 捨 て ら れ た 部 分 は 失 わ れ る )。 MSG_NOERROR が 指 定 さ れ て い な け れ ば 、 メ ッ セ ー ジ は キ ュ ー か ら 削 除 さ れ ず 、 シ ス テ ム コ ー ル は -1 を 返 し て 失 敗 し 、 errno E2BIG が 設 定 さ れ る 。

MSG_COPY msgflg に 指 定 さ れ て い な い 場 合 (下 記 参 照 )、 msgtyp 引 数 に は 要 求 す る メ ッ セ ー ジ の 型 を 指 定 す る 。 型 は 以 下 の よ う に 指 定 す る :

msgtyp が 0 な ら ば 、 キ ュ ー の 最 初 に あ る メ ッ セ ー ジ が 読 み 込 ま れ る 。

msgtyp が 0 よ り 大 き い 場 合 、 msgflg MSG_EXCEPT が 指 定 さ れ て い な け れ ば 、 msgtyp 型 の キ ュ ー の 最 初 の メ ッ セ ー ジ が 読 み 込 ま れ る 。 MSG_EXCEPT が 指 定 さ れ た 場 合 は 、 msgtyp 型 以 外 の キ ュ ー の 最 初 の メ ッ セ ー ジ が 読 み 込 ま れ る 。

msgtyp が 0 よ り 小 さ け れ ば 、 msgtyp の 絶 対 値 以 下 で 最 も 小 さ い 型 を 持 つ キ ュ ー の 最 初 の メ ッ セ ー ジ が 読 み 込 ま れ る 。

msgflg 引 数 に は 、 以 下 の フ ラ グ を 任 意 の 数 だ け (0個 も 可 )、 こ れ ら の OR で 指 定 す る :
IPC_NOWAIT

キ ュ ー に 要 求 さ れ た 型 の メ ッ セ ー ジ が な い 場 合 に は 直 ち に 返 る 。 シ ス テ ム コ ー ル は 失 敗 し 、 errno に は ENOMSG が 設 定 さ れ る 。

MSG_COPY (Linux 3.8 以 降 )

キ ュ ー の 中 で msgtyp で 指 定 し た 位 置 に あ る メ ッ セ ー ジ の コ ピ ー を 、 キ ュ ー を 変 更 せ ず に (非 破 壊 的 に ) 取 り 出 す (メ ッ セ ー ジ の 位 置 は 0 か ら 順 番 に 番 号 が 割 り 当 て ら れ る )。

こ の フ ラ グ は IPC_NOWAIT と 組 み 合 わ せ て 指 定 し な け れ ば な ら な い 。 そ の 結 果 、 指 定 し た 位 置 に メ ッ セ ー ジ が な か っ た 場 合 、 呼 び 出 し は エ ラ ー ENOMSG で す ぐ に 失 敗 す る 。 MSG_COPY MSG_EXCEPT msgtyp の 意 味 を 相 容 れ な い 方 法 で 使 用 す る た め 、 こ の 二 つ の フ ラ グ の 両 方 を msgtyp に 指 定 す る こ と は で き な い 。

MSG_COPY フ ラ グ は 、 カ ー ネ ル の チ ェ ッ ク ポ イ ン ト 復 元 (checkpoint-restore) 機 能 の 実 装 の た め に 追 加 さ れ た 。 こ の フ ラ グ は カ ー ネ ル が CONFIG_CHECKPOINT_RESTORE オ プ シ ョ ン を 有 効 に し て 作 成 さ れ た 場 合 に の み 利 用 で き る 。

MSG_EXCEPT

0 よ り 大 き な msgtyp と 一 緒 に 使 用 し て 、 msgtyp 以 外 の キ ュ ー の 最 初 の メ ッ セ ー ジ を 読 み 込 む 。

MSG_NOERROR

msgsz バ イ ト よ り も 長 か っ た 場 合 は メ ッ セ ー ジ の テ キ ス ト を 切 り 詰 め る 。

要 求 さ れ た 型 の メ ッ セ ー ジ が 存 在 せ ず 、 msgflg IPC_NOWAIT が 指 定 さ れ て い な か っ た 場 合 、 呼 び 出 し 元 プ ロ セ ス は 以 下 の い ず れ か の 状 況 に な る ま で 停 止 (block) さ れ る :

要 求 し て い る 型 の メ ッ セ ー ジ が キ ュ ー へ 入 れ ら れ た 。

メ ッ セ ー ジ キ ュ ー が シ ス テ ム か ら 削 除 さ れ た 。 こ の 場 合 、 シ ス テ ム コ ー ル は 失 敗 し 、 errno EIDRM が 設 定 さ れ る 。

呼 び 出 し 元 プ ロ セ ス が シ グ ナ ル を 捕 獲 し た 。 こ の 場 合 、 シ ス テ ム コ ー ル は 失 敗 し 、 errno EINTR が 設 定 さ れ る 。 ( msgrcv () は 、 た と え シ グ ナ ル ハ ン ド ラ ー の 設 定 時 に SA_RESTART を 指 定 し て い た と し て も 、 シ グ ナ ル ハ ン ド ラ ー に よ っ て 割 り 込 ま れ た 後 で 自 動 的 に 再 ス タ ー ト す る こ と は 決 し て な い 。 )

正 常 に 終 了 し た 場 合 、 メ ッ セ ー ジ キ ュ ー の デ ー タ 構 造 体 は 以 下 の よ う に 更 新 さ れ る :

msg_lrpid に は 呼 び 出 し 元 プ ロ セ ス の プ ロ セ ス ID が 設 定 さ れ る 。

msg_qnum は 1 減 算 さ れ る 。

msg_rtime に は 現 在 の 時 刻 が 設 定 さ れ る 。

返 り 値

失 敗 し た 場 合 は 、 ど ち ら の 関 数 も -1 を 返 し 、 エ ラ ー を errno に 表 示 す る 。 成 功 し た 場 合 、 msgsnd () は 0 を 返 し 、 msgrcv () は mtext 配 列 に 実 際 に コ ピ ー し た バ イ ト 数 を 返 す 。

エ ラ ー

msgsnd () が 失 敗 し た 場 合 、 errno に 以 下 の 値 の い ず れ か が 設 定 さ れ る :

EACCES

The calling process does not have write permission on the message queue, and does not have the CAP_IPC_OWNER capability in the user namespace that governs its IPC namespace.

EAGAIN

msg_qbytes が キ ュ ー の 制 限 を 超 え て い た た め 、 メ ッ セ ー ジ を 送 る こ と が で き ず 、 か つ msgflg IPC_NOWAIT が 指 定 さ れ て い た 。

EFAULT

msgp が 指 し て い る ア ド レ ス が ア ク セ ス 可 能 で な い 。

EIDRM

メ ッ セ ー ジ キ ュ ー が 削 除 さ れ た 。

EINTR

メ ッ セ ー ジ キ ュ ー が 要 求 し た 条 件 を 満 た す ま で 停 止 し て い る 時 に 、 プ ロ セ ス が シ グ ナ ル を 捕 獲 し た 。

EINVAL

msqid が 不 適 切 な 値 で あ る か 、 mtype が 正 の 値 で な い か 、 msgsz が 不 適 切 な 値 (0 以 下 か 、 シ ス テ ム で 決 ま る 値 MSGMAX よ り も 大 き い 値 ) で あ る 。

ENOMEM

msgp が 指 す メ ッ セ ー ジ の コ ピ ー を 作 成 す る の に 十 分 な メ モ リ ー が シ ス テ ム に 存 在 し な い 。

msgrcv () が 失 敗 し た 場 合 に は errno に 以 下 の 値 の い ず れ か が 設 定 さ れ る :

E2BIG

メ ッ セ ー ジ の テ キ ス ト の 長 さ が msgsz よ り も 大 き く 、 msgflg MSG_NOERROR が 設 定 さ れ て い な か っ た 。

EACCES

The calling process does not have read permission on the message queue, and does not have the CAP_IPC_OWNER capability in the user namespace that governs its IPC namespace.

EFAULT

msgp が 指 し て い る ア ド レ ス が ア ク セ ス 可 能 で な い 。

EIDRM

メ ッ セ ー ジ を 受 信 す る た め に プ ロ セ ス が 停 止 し て い る 間 に 、 メ ッ セ ー ジ キ ュ ー が 削 除 さ れ た 。

EINTR

メ ッ セ ー ジ を 受 け る た め に プ ロ セ ス が 停 止 し て い る 間 に 、 プ ロ セ ス が シ グ ナ ル を 捕 獲 し た 。 signal (7) 参 照 。

EINVAL

msgid が 不 正 か 、 msgsz が 0 よ り 小 さ い 。

EINVAL (Linux 3.14 以 降 )

msgflg MSG_COPY が 指 定 さ れ た が 、 IPC_NOWAIT が 指 定 さ れ て い な い 。

EINVAL (Linux 3.14 以 降 )

msgflg MSG_COPY MSG_EXCEPT の 両 方 が 指 定 さ れ た 。

ENOMSG

msgflg IPC_NOWAIT が 設 定 さ れ て お り 、 メ ッ セ ー ジ キ ュ ー に 要 求 さ れ た 型 の メ ッ セ ー ジ が 存 在 し な か っ た 。

ENOMSG

IPC_NOWAIT MSG_COPY msgflg に 指 定 さ れ た が 、 キ ュ ー に は msgtyp 未 満 の メ ッ セ ー ジ し か 入 っ て い な か っ た 。

ENOSYS (Linux 3.8 以 降 )

msgflg MSG_COPY IPC_NOWAIT の 両 方 が 指 定 さ れ た が 、 カ ー ネ ル が CONFIG_CHECKPOINT_RESTORE な し で 作 成 さ れ て い る 。

準 拠

POSIX.1-2001, POSIX.1-2008, SVr4.

フ ラ グ MSG_EXCEPT MSG_COPY は Linux 固 有 で あ る 。 こ れ ら の 定 義 を 得 る に は 、 機 能 検 査 マ ク ロ _GNU_SOURCE を 定 義 す る 。

注 意

Linux や POSIX の 全 て の バ ー ジ ョ ン で は 、 <sys/types.h> <sys/ipc.h> の イ ン ク ル ー ド は 必 要 な い 。 し か し な が ら 、 い く つ か の 古 い 実 装 で は こ れ ら の ヘ ッ ダ ー フ ァ イ ル の イ ン ク ル ー ド が 必 要 で あ り 、 SVID で も こ れ ら の イ ン ク ル ー ド を す る よ う に 記 載 さ れ て い る 。 こ の よ う な 古 い シ ス テ ム へ の 移 植 性 を 意 図 し た ア プ リ ケ ー シ ョ ン で は こ れ ら の フ ァ イ ル を イ ン ク ル ー ド す る 必 要 が あ る か も し れ な い 。

msgp 引 数 は 、 glibc 2.0 と 2.1 で は struct msgbuf * と 宣 言 さ れ て い る 。 glibc 2.2 以 降 で は 、 SUSv2 と SUSv3 の 要 求 通 り 、 void * と 宣 言 さ れ て い る 。

以 下 は msgsnd シ ス テ ム コ ー ル に 影 響 す る シ ス テ ム 制 限 で あ る :

MSGMAX

Maximum size of a message text, in bytes (default value: 8192 bytes). On Linux, this limit can be read and modified via /proc/sys/kernel/msgmax .

MSGMNB

Maximum number of bytes that can be held in a message queue (default value: 16384 bytes). On Linux, this limit can be read and modified via /proc/sys/kernel/msgmnb . A privileged process (Linux: a process with the CAP_SYS_RESOURCE capability) can increase the size of a message queue beyond MSGMNB using the msgctl (2) IPC_SET operation.

現 在 の 実 装 で は 、 シ ス テ ム 全 体 の メ ッ セ ー ジ ヘ ッ ダ ー の 上 限 数 ( MSGTQL ) と 、 シ ス テ ム 全 体 の メ ッ セ ー ジ プ ー ル の 最 大 バ イ ト 数 ( MSGPOOL ) に 関 し て 実 装 依 存 の 制 限 は な い 。

バ グ

Linux 3.13 以 前 で は 、 msgrcv () の 呼 び 出 し で MSG_COPY フ ラ グ は 指 定 さ れ た が IPC_NOWAIT は 指 定 さ れ ず 、 か つ メ ッ セ ー ジ キ ュ ー に msgtyp 未 満 の メ ッ セ ー ジ し か な い 場 合 に 、 msgrcv () の 呼 び 出 し は キ ュ ー に 次 の メ ッ セ ー ジ が 書 き 込 ま れ る ま で 停 止 し て い た 。 新 し い メ ッ セ ー ジ が 書 き 込 ま れ た 時 点 で 、 そ の メ ッ セ ー ジ が 指 定 さ れ た 位 置 msgtyp か ど う か に 関 わ ら ず msgrcv () の 呼 び 出 し は 新 た に 書 き 込 ま れ た メ ッ セ ー ジ の コ ピ ー を 返 し て い た 。 こ の バ グ は Linux 3 . 1 4 で 修 正 さ れ た 。

msg_copy MSG_COPY MSG_EXCEPT の 両 方 を 指 定 す る の は 、 論 理 的 な エ ラ ー で あ る (な ぜ な ら こ れ ら の フ ラ グ は msgtyp を 別 の 意 味 で 解 釈 す る か ら で あ る )。 Linux 3.13 以 前 で は 、 msgrcv () が こ の エ ラ ー を 検 出 し な か っ た 。 こ の バ グ は Linux 3.14 で 修 正 さ れ た 。

The program below demonstrates the use of msgsnd () and msgrcv ().

The example program is first run with the -s option to send a message and then run again with the -r option to receive a message.

The following shell session shows a sample run of the program:

$ ./a.out -s
sent: a message at Wed Mar 4 16:25:45 2015

$ ./a.out -r
message received: a message at Wed Mar 4 16:25:45 2015

プ ロ グ ラ ム の ソ ー ス

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct msgbuf {
long mtype;
char mtext[80];
};

static void
usage(char *prog_name, char *msg)
{
if (msg != NULL)
fputs(msg, stderr);

fprintf(stderr, "Usage: %s [options]\n", prog_name);
fprintf(stderr, "Options are:\n");
fprintf(stderr, "-s send message using msgsnd()\n");
fprintf(stderr, "-r read message using msgrcv()\n");
fprintf(stderr, "-t message type (default is 1)\n");
fprintf(stderr, "-k message queue key (default is 1234)\n");
exit(EXIT_FAILURE);
}

static void
send_msg(int qid, int msgtype)
{
struct msgbuf msg;
time_t t;

msg.mtype = msgtype;

time(&t);
snprintf(msg.mtext, sizeof(msg.mtext), "a message at %s",
ctime(&t));

if (msgsnd(qid, &msg, sizeof(msg.mtext),
IPC_NOWAIT) == -1) {
perror("msgsnd error");
exit(EXIT_FAILURE);
}
printf("sent: %s\n", msg.mtext);
}

static void
get_msg(int qid, int msgtype)
{
struct msgbuf msg;

if (msgrcv(qid, &msg, sizeof(msg.mtext), msgtype,
MSG_NOERROR | IPC_NOWAIT) == -1) {
if (errno != ENOMSG) {
perror("msgrcv");
exit(EXIT_FAILURE);
}
printf("No message available for msgrcv()\n");
} else
printf("message received: %s\n", msg.mtext);
}

int
main(int argc, char *argv[])
{
int qid, opt;
int mode = 0; /* 1 = send, 2 = receive */
int msgtype = 1;
int msgkey = 1234;

while ((opt = getopt(argc, argv, "srt:k:")) != -1) {
switch (opt) {
case 's':
mode = 1;
break;
case 'r':
mode = 2;
break;
case 't':
msgtype = atoi(optarg);
if (msgtype <= 0)
usage(argv[0], "-t option must be greater than 0\n");
break;
case 'k':
msgkey = atoi(optarg);
break;
default:
usage(argv[0], "Unrecognized option\n");
}
}

if (mode == 0)
usage(argv[0], "must use either -s or -r option\n");

qid = msgget(msgkey, IPC_CREAT | 0666);

if (qid == -1) {
perror("msgget");
exit(EXIT_FAILURE);
}

if (mode == 2)
get_msg(qid, msgtype);
else
send_msg(qid, msgtype);

exit(EXIT_SUCCESS);
}

関 連 項 目

msgctl (2), msgget (2), capabilities (7), mq_overview (7), sysvipc (7)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。