Interprocess Communication on UNIX SVR3

Greg Hackney mechjgh at tness7.UUCP
Thu Apr 21 09:36:34 AEST 1988


In article <2592 at ihuxv.ATT.COM> bareta at ihuxv.ATT.COM (Benyukhis) writes:
>the producer has to produce
>a char and deposit it in the shareable buffer for consumer to pick it up
>from.  Both processes must use binary semaphores as a means of
>synchronization.  It looks trivial, but for someone that has never
>written anything for more than one process

I'm not sure if this is what you want, but here are 4 simple
demo programs for writing lines of IPC "messages", open.c, send.c,
receive.c, and close.c.

open 777       # opens a message queue
ipcs           # show the queue status
send 777 text  # send some text
ipcs           # show the queue status
send 777 text1 # send some more text
ipcs           # show the queue status
rec 777        # read some text
rec 777        # read some text
close 777      # close the queue
ipcs           # show the queue status

--
Greg
{ihnp4 | bellcore}!tness1!mechjgh

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	close.c
#	open.c
#	rec.c
#	send.c
# This archive created: Wed Apr 20 18:19:26 1988
export PATH; PATH=/bin:$PATH
if test -f 'close.c'
then
	echo shar: over-writing existing file "'close.c'"
fi
cat << \SHAR_EOF > 'close.c'
/*  close.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

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

	int qid;
	int syserr();

	/*see if the queue is open, and get queue ID number */
	if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1)
		syserr("Queue was not open!\n");

	/*close the queue*/
	if((msgctl(qid,IPC_RMID,NULL)) == -1)
		syserr("Can't close the queue\n");

	printf("Queue closed successfully\n");
	exit(0);
}

syserr(msg)
char *msg;
{
	extern int errno, sys_nerr;
	extern char *sys_errlist[];

	fprintf(stderr,"ERROR: %s (%d", msg, errno);
	if(errno > 0 && errno < sys_nerr)
		fprintf(stderr, ";%s)\n", sys_errlist[errno]);
	else
		fprintf(stderr,")\n");
	exit(1);
}

SHAR_EOF
if test -f 'open.c'
then
	echo shar: over-writing existing file "'open.c'"
fi
cat << \SHAR_EOF > 'open.c'
/*open.c*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define MAXOPEN 20

main(argc,argv)
int argc;
char *argv[];
{
	int id;
	int syserr();

	if((id=openqueue(atoi(argv[1]))) == -1)
		syserr("Can't open a queue\n");
	printf("Queue ID is %ld\n",id);
	exit(0);
}


static int openqueue(key) /* return queue ID; create if necessary */
long key;
{
	static struct{ 
		long key;
		int qid;
	}queues[MAXOPEN];
	int i, avail, qid;
	extern int errno;
	
	avail = -1;
	for(i=0; i < MAXOPEN; i++){
		if(queues[i].key == key)
			return(queues[i].qid);
		if(queues[i].key == 0 && avail == -1)
			avail=i;
	}
	if(avail == -1){
		errno=0;
		return(-1);
	}
	if((qid=msgget(key,0666 | IPC_CREAT))== -1)
		return(-1);
	queues[avail].key = key;
	queues[avail].qid = qid;
	return(qid);
}

syserr(msg)
char *msg;
{
	extern int errno, sys_nerr;
	extern char *sys_errlist[];

	fprintf(stderr,"ERROR: %s (%d", msg, errno);
	if(errno > 0 && errno < sys_nerr)
		fprintf(stderr, ";%s)\n", sys_errlist[errno]);
	else
		fprintf(stderr,")\n");
	exit(1);
}

SHAR_EOF
if test -f 'rec.c'
then
	echo shar: over-writing existing file "'rec.c'"
fi
cat << \SHAR_EOF > 'rec.c'
/*receive.c*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define MSGSIZE 100

struct foo {
	long	mtype;		/* message type */
	char	mtext[100];	/* message text */
};

struct foo buf;

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

	int qid;
	int ret;
	int syserr();

	/* check to see if the message queue has been opened,
           and get the queue ID number */
	if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1)
		syserr("Queue was not open!\n");
	printf("Got a qid of %d\n",qid);

	/*set the message type*/
	buf.mtype=1;

	/*get the message from queue */
	if((msgrcv(qid,&buf,sizeof(buf) - sizeof(buf.mtype),0L,0)) == -1){
		printf("Return was %d\n",ret);
		syserr("Can't read the queue\n");
		}
	printf("Return was %d\n",ret);
	printf("%s\n",buf.mtext);
	exit(0);
}

syserr(msg)
char *msg;
{
	extern int errno, sys_nerr;
	extern char *sys_errlist[];

	fprintf(stderr,"ERROR: %s (%d", msg, errno);
	if(errno > 0 && errno < sys_nerr)
		fprintf(stderr, ";%s)\n", sys_errlist[errno]);
	else
		fprintf(stderr,")\n");
	exit(1);
}

SHAR_EOF
if test -f 'send.c'
then
	echo shar: over-writing existing file "'send.c'"
fi
cat << \SHAR_EOF > 'send.c'
/*send.c*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define MSGSIZE 100

struct foo {
	long	mtype;		/* message type */
	char	mtext[100];	/* message text */
};

struct foo BUF;

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

	int qid;
	int ret;
	int syserr();

	/*see if the queue is open, and get the queue ID */
	if((qid=msgget(atoi(argv[1]),0666 & ~IPC_CREAT))== -1)
		syserr("Queue was not open!\n");

	/*set the message type*/
	BUF.mtype = 1;
	sprintf(BUF.mtext,"%s\0",argv[2]);

	/*put the message in queue*/
	if((ret=msgsnd(qid,&BUF,sizeof(BUF) - sizeof(BUF.mtype),0)) == -1)
		syserr("Can't send the queue\n");
	printf("Return was %d\n",ret);
	printf("Message queued successfully\n");
	exit(0);
}

syserr(msg)
char *msg;
{
	extern int errno, sys_nerr;
	extern char *sys_errlist[];

	fprintf(stderr,"ERROR: %s (%d", msg, errno);
	if(errno > 0 && errno < sys_nerr)
		fprintf(stderr, ";%s)\n", sys_errlist[errno]);
	else
		fprintf(stderr,")\n");
	exit(1);
}

SHAR_EOF
#	End of shell archive
exit 0



More information about the Comp.unix.xenix mailing list