ryochack
8/16/2013 - 5:35 PM

msgqueue_ack.c

// process communication using message queue
// ack version
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MSGLEN (16)

enum {
	MSGTYPE_TEXT = 1,
	MSGTYPE_ACK,
};

struct msgbuf {
	long type;
	char text[MSGLEN];
};

void die(const char* msg) {
	perror(msg);
	exit(1);
}

int main() {
	int i;

	// get key
	key_t msgkey = ftok("temp", 'A');
	if (msgkey == -1) die("ftok()");
	int msgqid = msgget(msgkey, IPC_CREAT);
	if (msgqid == -1) die("msgget()");

	pid_t pid = fork();
	if (pid < 0) {
		die("fork()");
	} else if (pid == 0) {
		// child process
		struct msgbuf msgs[6];
		struct msgbuf ack;
		const char* texts[] = {"first", "second", "third", "forth", "fifth", "q"};
		while (1) {
			msgs[i].type = MSGTYPE_TEXT;
			strcpy(msgs[i].text, texts[i]);
			if (msgsnd(msgqid, &msgs[i], MSGLEN, 0) == -1) die("msgsnd()");
			if (msgrcv(msgqid, &ack, MSGLEN, MSGTYPE_ACK, 0) == -1) die("ackrcv()");
			printf("snd %s\n", msgs[i].text);
			if (msgs[i].text[0] == 'q') break;
			i++;
		}
		return 1;
	} else {
		// parent process
		struct msgbuf msg;
		struct msgbuf ack = {MSGTYPE_ACK, ""};
		while (1) {
			if (msgrcv(msgqid, &msg, MSGLEN, MSGTYPE_TEXT, 0) == -1) die("msgrcv()");
			if (msgsnd(msgqid, &ack, MSGLEN, 0) == -1) die("acksnd()");
			printf("rcv %s\n", msg.text);
			if (msg.text[0] == 'q') break;
		}
		return 2;
	}
}