POSIX メッセージキュー リベンジ編

前回:http://d.hatena.ne.jp/debian36/20080220/1203510497
ちょっと前に挑戦して、うまくいかなかったPOSIX メッセージキューを用いたIPCプログラミング。

いろいろ試した結果、前回の ERRNO 90 (ELOOP) の原因は、
mq_receive 時のバッファサイズ指定ミスのようでした。

SysVのMsgQだと、メッセージキューそのものの属性がどうであろうと、
そのときに(msgrcvコール時に)取得するメッセージ以上のサイズをmsgrcv()のlength引数に渡せばよかったのですが、
POSIXのMsgQの場合、実際に格納されているメッセージのサイズがどうであろうと、対象となるメッセージキューに格納されうる最大のサイズを mq_receive() のlen 引数に渡さなければいけないようです。

そのため、mq_receive()する前に、
mq_getattr()を用いて、メッセージキューの属性として定義されている メッセージキューが保持できるメッセージの最大サイズ を取得しておく必要があります。

そのサイズをもとに、メッセージ受け取り用バッファ分のメモリを獲得し、
mq_receiveをコールします。

defs.h

#define QPATH "/msgQ"

typedef struct{
	char str[100];
}MSG;

enq.c

#include 
#include 
#include 
#include 
#include "defs.h"

int main(void){
	mqd_t qid;
	MSG obj = {"Hello POSIX MsgQ!"};
	int ret;

	mq_unlink(QPATH);
	
	qid = mq_open(QPATH, O_RDWR|O_CREAT, S_IRWXU|S_IRWXO, NULL);
	printf("qid : %d\n",qid);

	ret = mq_send(qid, &obj, sizeof(MSG), 0);
	printf("ret : %d\n",ret);

	return 0;
}

deq.c

#include 
#include 
#include 
#include 
#include 
#include "./defs.h"
#include 

int main(void){
	mqd_t qid;
	int ret;
	void* buf;
	struct mq_attr attr;

	qid = mq_open(QPATH, O_RDWR);
	printf("qid : %d\n",qid);

	mq_getattr(qid, &attr);
	printf("msgsize : %d\n",attr.mq_msgsize);

	buf = malloc(attr.mq_msgsize);

	ret = mq_receive(qid, buf, attr.mq_msgsize, NULL);
	printf("ret : %d\n",ret);
	printf("errno : %d\n",errno);

	printf("Received Message : %s\n",((MSG*)buf)->str);

	return 0;
}


実行結果

debian36 # ./enq
qid : 3
ret : 0
debian36 # ./deq
qid : 3
msgsize : 8192
ret : 100
errno : 0
Received Message : Hello POSIX MsgQ!