0% found this document useful (0 votes)
5 views3 pages

Program 5

This document provides a C code example for a message queue implementation using System V IPC. It includes command line instructions for sending and receiving messages, as well as parsing command line arguments with getopt(). The code demonstrates the setup of a message queue, sending and receiving messages, and handling errors appropriately.

Uploaded by

jadhavshital8110
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views3 pages

Program 5

This document provides a C code example for a message queue implementation using System V IPC. It includes command line instructions for sending and receiving messages, as well as parsing command line arguments with getopt(). The code demonstrates the setup of a message queue, sending and receiving messages, and handling errors appropriately.

Uploaded by

jadhavshital8110
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

/*

* Message Queue example


*
* Written by Ori Idan Based on demonstration by Gilad Ben-Yosef of codefidence
Ltd.
*
* To send a message use ./msgqueue -t n -s "message"
* To receive a message use ./msgqueue -r -t n
* n - is message type
*
* In addition to demonstrating message queues this example also shows how to use
getopt() to
* parse command line arguments
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define MAX_MSG_SIZE (255)


#define DEFAULT_TYPE (1)
#define MAX_TYPE (65536)

enum op_mode { NULL_MODE, RECV_MODE, SEND_MODE };

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

enum op_mode mode = NULL_MODE;


int msgtype = 0;
char * arg = NULL;
unsigned char blocking = 0;

/* Helper Functions */

/* Translate state to msgrcv/msgsnd msg_flags field */


int inline msg_flags(void) {
return (blocking ? 0 : IPC_NOWAIT);
}

void usage(char *str)


{
printf("%s [-s message | -r] [-t type]\n -s messages: send the specified
message.\n"
" -r: reciecve a message.\n -t type: use specified type, from 1 to
65536 for receive or send.\n",
str);
exit(0);
}

/* Parse command line and initalize state accordingly */


void parse_param(int argc, char *argv[])
{
int opt;

while((opt = getopt(argc, argv, "s:t:rn")) != -1) {


switch(opt) {
case 'r':
mode = RECV_MODE;
if(msgtype == 0)
msgtype = -MAX_PRIORITY;
break;
case 's':
mode = SEND_MODE;
arg = optarg;
if(msgtype == 0)
msgtype = DEFAULT_TYPE;
break;
case 'n':
blocking=1;
break;
case 't':
msgtype = atoi(optarg);
if((msgtype <= 0) || (msgtype > MAX_PRIORITY)) {
printf("Invalid type requested.\n");
usage(argv[0]);
}
break;
default:
usage(argv[0]);
}
}

if(mode == NULL_MODE)
usage(argv[0]);

return;
}

int main(int argc, char * argv[])


{
key_t qkey; /* This is the SysV IPC key */
int msgqid; /* The queue handle */
struct msgbuf my_msg; /* This is the message buffer */
char *err_reason = NULL;

parse_param(argc, argv);

/* Obtain queue key */


qkey = ftok(argv[0], 0);

if(qkey == -1) {
printf("ERROR! %s: %s\n", "failed getting queue key",
strerror(errno));
return errno;
}

/* Open queue for read and write, creating it if needed */


msgqid = msgget(qkey, S_IRWXU | IPC_CREAT);
if(msgqid == -1) {
printf("ERROR! %s: %s\n", "failed getting queue id",
strerror(errno));
return errno;
}

switch(mode) {
case RECV_MODE:
/* Recieve a message, blocking for it if requested */
do {
if(msgrcv(msgqid, &my_msg, MAX_MSG_SIZE, msgtype,
msg_flags()) == -1) {
if (errno != EINTR) {
printf("ERROR! %s: %s\n", "failed
to receive a message",
strerror(errno));
return errno;
}
}
/* If we got a signal in the middle of operation,
we will have to redo it.
This is especially of concern if we block. */
} while (errno == EINTR);
printf("Message of type %d recevied: %s\n", my_msg.mtype,
my_msg.mtext);
break;
case SEND_MODE:
/* Prepare a message to send */
strncpy(my_msg.mtext, arg, MAX_MSG_SIZE);
my_msg.mtype = msgtype;

/* Send a message, blocking for it if requested */


do {
/* See remark about signals above */
if(msgsnd(msgqid, &my_msg, MAX_MSG_SIZE,
msg_flags()) == -1) {
if (errno != EINTR) {
printf("ERROR! %s: %s\n", "failed
to send a message",
strerror(errno));
return(errno);
}
}
} while (errno == EINTR);
printf("Message sent.\n");
break;
default:
printf("ERROR! This should never happen!\n");
exit(2);
}
return 0;
}

You might also like