Compile the two programs separately Execute them in differen
Compile the two programs separately. Execute them in different sequences and in different shells.
Document your observations.
Modify the code such that the sender and the receiver provide the following output:
(Process 1) Sends the message \"Are you hearing me?\"
(Process 2) Receives the message and replies \"Loud and Clear\".
(Process 1) Receives the reply and then says \"I can hear you too\".
Solution
#include <stdio.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
extern void exit();
 extern void perror();
main()
 {
 key_t key;
 int msgflg,
 msqid;
(void) fprintf(stderr,
 \"All numeric input is expected to follow C conventions:\ \");
 (void) fprintf(stderr,
 \"\\t0x... is interpreted as hexadecimal,\ \");
 (void) fprintf(stderr, \"\\t0... is interpreted as octal,\ \");
 (void) fprintf(stderr, \"\\totherwise, decimal.\ \");
 (void) fprintf(stderr, \"IPC_PRIVATE == %#lx\ \", IPC_PRIVATE);
 (void) fprintf(stderr, \"Enter key: \");
 (void) scanf(\"%li\", &key);
 (void) fprintf(stderr, \"\ Expected flags for msgflg argument
 are:\ \");
 (void) fprintf(stderr, \"\\tIPC_EXCL =\\t%#8.8o\ \", IPC_EXCL);
 (void) fprintf(stderr, \"\\tIPC_CREAT =\\t%#8.8o\ \", IPC_CREAT);
 (void) fprintf(stderr, \"\\towner read =\\t%#8.8o\ \", 0400);
 (void) fprintf(stderr, \"\\towner write =\\t%#8.8o\ \", 0200);
 (void) fprintf(stderr, \"\\tgroup read =\\t%#8.8o\ \", 040);
 (void) fprintf(stderr, \"\\tgroup write =\\t%#8.8o\ \", 020);
 (void) fprintf(stderr, \"\\tother read =\\t%#8.8o\ \", 04);
 (void) fprintf(stderr, \"\\tother write =\\t%#8.8o\ \", 02);
 (void) fprintf(stderr, \"Enter msgflg value: \");
 (void) scanf(\"%i\", &msgflg);
(void) fprintf(stderr, \"\ msgget: Calling msgget(%#lx,
 %#o)\ \",
 key, msgflg);
 if ((msqid = msgget(key, msgflg)) == -1)
 {
 perror(\"msgget: msgget failed\");
 exit(1);
 } else {
 (void) fprintf(stderr,
 \"msgget: msgget succeeded: msqid = %d\ \", msqid);
 exit(0);
 }
 }
 msgctl.cSample Program to Illustrate msgctl()
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 #include <time.h>
static void do_msgctl();
 extern void exit();
 extern void perror();
 static char warning_message[] = \"If you remove read permission
 for \\
 yourself, this program will fail frequently!\";
main()
 {
 struct msqid_ds buf; /* queue descriptor buffer for IPC_STAT
 and IP_SET commands */
 int cmd, /* command to be given to msgctl() */
 msqid; /* queue ID to be given to msgctl() */
(void fprintf(stderr,
 \"All numeric input is expected to follow C conventions:\ \");
 (void) fprintf(stderr,
 \"\\t0x... is interpreted as hexadecimal,\ \");
 (void) fprintf(stderr, \"\\t0... is interpreted as octal,\ \");
 (void) fprintf(stderr, \"\\totherwise, decimal.\ \");
/* Get the msqid and cmd arguments for the msgctl() call. */
 (void) fprintf(stderr,
 \"Please enter arguments for msgctls() as requested.\");
 (void) fprintf(stderr, \"\ Enter the msqid: \");
 (void) scanf(\"%i\", &msqid);
 (void) fprintf(stderr, \"\\tIPC_RMID = %d\ \", IPC_RMID);
 (void) fprintf(stderr, \"\\tIPC_SET = %d\ \", IPC_SET);
 (void) fprintf(stderr, \"\\tIPC_STAT = %d\ \", IPC_STAT);
 (void) fprintf(stderr, \"\ Enter the value for the command: \");
 (void) scanf(\"%i\", &cmd);
switch (cmd) {
 case IPC_SET:
 /* Modify settings in the message queue control structure.
 */
 (void) fprintf(stderr, \"Before IPC_SET, get current
 values:\");
 /* fall through to IPC_STAT processing */
 case IPC_STAT:
 /* Get a copy of the current message queue control
 * structure and show it to the user. */
 do_msgctl(msqid, IPC_STAT, &buf);
 (void) fprintf(stderr, ]
 \"msg_perm.uid = %d\ \", buf.msg_perm.uid);
 (void) fprintf(stderr,
 \"msg_perm.gid = %d\ \", buf.msg_perm.gid);
 (void) fprintf(stderr,
 \"msg_perm.cuid = %d\ \", buf.msg_perm.cuid);
 (void) fprintf(stderr,
 \"msg_perm.cgid = %d\ \", buf.msg_perm.cgid);
 (void) fprintf(stderr, \"msg_perm.mode = %#o, \",
 buf.msg_perm.mode);
 (void) fprintf(stderr, \"access permissions = %#o\ \",
 buf.msg_perm.mode & 0777);
 (void) fprintf(stderr, \"msg_cbytes = %d\ \",
 buf.msg_cbytes);
 (void) fprintf(stderr, \"msg_qbytes = %d\ \",
 buf.msg_qbytes);
 (void) fprintf(stderr, \"msg_qnum = %d\ \", buf.msg_qnum);
 (void) fprintf(stderr, \"msg_lspid = %d\ \",
 buf.msg_lspid);
 (void) fprintf(stderr, \"msg_lrpid = %d\ \",
 buf.msg_lrpid);
 (void) fprintf(stderr, \"msg_stime = %s\", buf.msg_stime ?
 ctime(&buf.msg_stime) : \"Not Set\ \");
 (void) fprintf(stderr, \"msg_rtime = %s\", buf.msg_rtime ?
 ctime(&buf.msg_rtime) : \"Not Set\ \");
 (void) fprintf(stderr, \"msg_ctime = %s\",
 ctime(&buf.msg_ctime));
 if (cmd == IPC_STAT)
 break;
 /* Now continue with IPC_SET. */
 (void) fprintf(stderr, \"Enter msg_perm.uid: \");
 (void) scanf (\"%hi\", &buf.msg_perm.uid);
 (void) fprintf(stderr, \"Enter msg_perm.gid: \");
 (void) scanf(\"%hi\", &buf.msg_perm.gid);
 (void) fprintf(stderr, \"%s\ \", warning_message);
 (void) fprintf(stderr, \"Enter msg_perm.mode: \");
 (void) scanf(\"%hi\", &buf.msg_perm.mode);
 (void) fprintf(stderr, \"Enter msg_qbytes: \");
 (void) scanf(\"%hi\", &buf.msg_qbytes);
 do_msgctl(msqid, IPC_SET, &buf);
 break;
 case IPC_RMID:
 default:
 /* Remove the message queue or try an unknown command. */
 do_msgctl(msqid, cmd, (struct msqid_ds *)NULL);
 break;
 }
 exit(0);
 }
/*
 * Print indication of arguments being passed to msgctl(), call
 * msgctl(), and report the results. If msgctl() fails, do not
 * return; this example doesn\'t deal with errors, it just reports
 * them.
 */
 static void
 do_msgctl(msqid, cmd, buf)
 struct msqid_ds *buf; /* pointer to queue descriptor buffer */
 int cmd, /* command code */
 msqid; /* queue ID */
 {
 register int rtrn; /* hold area for return value from msgctl()
 */
(void) fprintf(stderr, \"\ msgctl: Calling msgctl(%d, %d,
 %s)\ \",
 msqid, cmd, buf ? \"&buf\" : \"(struct msqid_ds *)NULL\");
 rtrn = msgctl(msqid, cmd, buf);
 if (rtrn == -1) {
 perror(\"msgctl: msgctl failed\");
 exit(1);
 } else {
 (void) fprintf(stderr, \"msgctl: msgctl returned %d\ \",
 rtrn);
 }
 }
 msgop.c: Sample Program to Illustrate msgsnd() and msgrcv()
/*
 * msgop.c: Illustrate the msgsnd() and msgrcv() functions.
 *
 * This is a simple exerciser of the message send and receive
 * routines. It allows the user to attempt to send and receive as
 many
 * messages as wanted to or from one message queue.
 */
#include <stdio.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
static int ask();
 extern void exit();
 extern char *malloc();
 extern void perror();
char first_on_queue[] = \"-> first message on queue\",
 full_buf[] = \"Message buffer overflow. Extra message text\\
 discarded.\";
main()
 {
 register int c; /* message text input */
 int choice; /* user\'s selected operation code */
 register int i; /* loop control for mtext */
 int msgflg; /* message flags for the operation */
 struct msgbuf *msgp; /* pointer to the message buffer */
 int msgsz; /* message size */
 long msgtyp; /* desired message type */
 int msqid, /* message queue ID to be used */
 maxmsgsz, /* size of allocated message buffer */
 rtrn; /* return value from msgrcv or msgsnd */
 (void) fprintf(stderr,
 \"All numeric input is expected to follow C conventions:\ \");
 (void) fprintf(stderr,
 \"\\t0x... is interpreted as hexadecimal,\ \");
 (void) fprintf(stderr, \"\\t0... is interpreted as octal,\ \");
 (void) fprintf(stderr, \"\\totherwise, decimal.\ \");
 /* Get the message queue ID and set up the message buffer. */
 (void) fprintf(stderr, \"Enter msqid: \");
 (void) scanf(\"%i\", &msqid);
 
 (void) fprintf(stderr,
 \"Enter the message buffer size you want:\");
 (void) scanf(\"%i\", &maxmsgsz);
 if (maxmsgsz < 0) {
 (void) fprintf(stderr, \"msgop: %s\ \",
 \"The message buffer size must be >= 0.\");
 exit(1);
 }
 msgp = (struct msgbuf *)malloc((unsigned)(sizeof(struct
 msgbuf)
 - sizeof msgp->mtext + maxmsgsz));
 if (msgp == NULL) {
 (void) fprintf(stderr, \"msgop: %s %d byte messages.\ \",
 \"could not allocate message buffer for\", maxmsgsz);
 exit(1);
 }
 /* Loop through message operations until the user is ready to
 quit. */
 while (choice = ask()) {
 switch (choice) {
 case 1: /* msgsnd() requested: Get the arguments, make the
 call, and report the results. */
 (void) fprintf(stderr, \"Valid msgsnd message %s\ \",
 \"types are positive integers.\");
 (void) fprintf(stderr, \"Enter msgp->mtype: \");
 (void) scanf(\"%li\", &msgp->mtype);
 if (maxmsgsz) {
   
 while ((c = getchar()) != \'\ \' && c != EOF);
 (void) fprintf(stderr, \"Enter a %s:\ \",
 \"one line message\");
 for (i = 0; ((c = getchar()) != \'\ \'); i++) {
 if (i >= maxmsgsz) {
 (void) fprintf(stderr, \"\ %s\ \", full_buf);
 while ((c = getchar()) != \'\ \');
 break;
 }
 msgp->mtext[i] = c;
 }
 msgsz = i;
 } else
 msgsz = 0;
 (void) fprintf(stderr,\"\ Meaningful msgsnd flag is:\ \");
 (void) fprintf(stderr, \"\\tIPC_NOWAIT =\\t%#8.8o\ \",
 IPC_NOWAIT);
 (void) fprintf(stderr, \"Enter msgflg: \");
 (void) scanf(\"%i\", &msgflg);
 (void) fprintf(stderr, \"%s(%d, msgp, %d, %#o)\ \",
 \"msgop: Calling msgsnd\", msqid, msgsz, msgflg);
 (void) fprintf(stderr, \"msgp->mtype = %ld\ \",
 msgp->mtype);
 (void) fprintf(stderr, \"msgp->mtext = \\\"\");
 for (i = 0; i < msgsz; i++)
 (void) fputc(msgp->mtext[i], stderr);
 (void) fprintf(stderr, \"\\\"\ \");
 rtrn = msgsnd(msqid, msgp, msgsz, msgflg);
 if (rtrn == -1)
 perror(\"msgop: msgsnd failed\");
 else
 (void) fprintf(stderr,
 \"msgop: msgsnd returned %d\ \", rtrn);
 break;
 case 2: /* msgrcv() requested: Get the arguments, make the
 call, and report the results. */
 for (msgsz = -1; msgsz < 0 || msgsz > maxmsgsz;
 (void) scanf(\"%i\", &msgsz))
 (void) fprintf(stderr, \"%s (0 <= msgsz <= %d): \",
 \"Enter msgsz\", maxmsgsz);
 (void) fprintf(stderr, \"msgtyp meanings:\ \");
 (void) fprintf(stderr, \"\\t 0 %s\ \", first_on_queue);
 (void) fprintf(stderr, \"\\t>0 %s of given type\ \",
 first_on_queue);
 (void) fprintf(stderr, \"\\t<0 %s with type <= |msgtyp|\ \",
 first_on_queue);
 (void) fprintf(stderr, \"Enter msgtyp: \");
 (void) scanf(\"%li\", &msgtyp);
 (void) fprintf(stderr,
 \"Meaningful msgrcv flags are:\ \");
 (void) fprintf(stderr, \"\\tMSG_NOERROR =\\t%#8.8o\ \",
 MSG_NOERROR);
 (void) fprintf(stderr, \"\\tIPC_NOWAIT =\\t%#8.8o\ \",
 IPC_NOWAIT);
 (void) fprintf(stderr, \"Enter msgflg: \");
 (void) scanf(\"%i\", &msgflg);
 (void) fprintf(stderr, \"%s(%d, msgp, %d, %ld, %#o);\ \",
 \"msgop: Calling msgrcv\", msqid, msgsz,
 msgtyp, msgflg);
 rtrn = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
 if (rtrn == -1)
 perror(\"msgop: msgrcv failed\");
 else {
 (void) fprintf(stderr, \"msgop: %s %d\ \",
 \"msgrcv returned\", rtrn);
 (void) fprintf(stderr, \"msgp->mtype = %ld\ \",
 msgp->mtype);
 (void) fprintf(stderr, \"msgp->mtext is: \\\"\");
 for (i = 0; i < rtrn; i++)
 (void) fputc(msgp->mtext[i], stderr);
 (void) fprintf(stderr, \"\\\"\ \");
 }
 break;
 default:
 (void) fprintf(stderr, \"msgop: operation unknown\ \");
 break;
 }
 }
 exit(0);
 }
 static
 ask()
 {
 int response; /* User\'s response. */
do {
 (void) fprintf(stderr, \"Your options are:\ \");
 (void) fprintf(stderr, \"\\tExit =\\t0 or Control-D\ \");
 (void) fprintf(stderr, \"\\tmsgsnd =\\t1\ \");
 (void) fprintf(stderr, \"\\tmsgrcv =\\t2\ \");
 (void) fprintf(stderr, \"Enter your choice: \");
 response = 0;
 (void) scanf(\"%i\", &response);
 } while (response < 0 || response > 2);
return(response);
 }
 Exercises






