[comp.unix.questions] System V.2 IPC

tony@artecon.UUCP (04/10/87)

Question about System V message passing (IPC):

In the man pages for msgop(2), it shows the message to be passed
as type *msgbuf.  The man pages say the struct is:

struct msgbuf{
	int	mtype;	/* type of message (arbitrary) */
	char	mtext[];	/* body of message */
	}

Now this implies that the pointer mtext can be assigned to an
array or can be malloc'd to. (which makes sense)

However, looking at the include file when this is defined <sys/msg.h>,
it defines the structure like this:

struct msgbuf {
	int	mtype;
	char	mtext[1];	/* note the '1' */
	}

What is going on here, I can't redefine this pointer, and I certainly
can't pass descent messages in *1* byte.

Of course the work around is obvious, define the structure myself as:

struct whatever {
	int	mtype;
	char	mtext[100];	/* or  char *mtype  */
	}

This works just fine, however, it is no longer portible code.
What if some versions of sys V (maybe some in the future) throw
in another flag.  Then my code is F*CKED.

So, anyone know the story??  This is not an isolated case, as both
HP-UX (based on sys V) and even Sun's System V compatibility mode
use this same definition (char mtext[1]).

Thanx in advance (as usual),
				    Tony

 
-- 
**************** Insert 'Standard' Disclaimer here:  OOP ACK! *****************
*  Tony Parkhurst -- {hplabs|sdcsvax|ncr-sd|hpfcla|ihnp4}!hp-sdd!artecon!adp  *
*                -OR-      hp-sdd!artecon!adp@nosc.ARPA                       *
*******************************************************************************

pdg@ihdev.UUCP (04/12/87)

In article <419@artecon.artecon.UUCP> tony@artecon.artecon.UUCP (Anthony D. Parkhurst) writes:

>Question about System V message passing (IPC):
> [ manual page excerpt editied out ]
>However, looking at the include file when this is defined <sys/msg.h>,
>it defines the structure like this:
>
>struct msgbuf {
>	int	mtype;
>	char	mtext[1];	/* note the '1' */
>	}
>
>What is going on here, I can't redefine this pointer, and I certainly
>can't pass descent messages in *1* byte.

They don't expect you to.  Just because it is one byte long in the
msgbuf definition, doesn't mean you must only pass 1 byte at a time.
You just allocate more space at the end of the structure, and
reference the space as mtext[index].  The standard SysV compiler does
not do any array-bounds checking, so this is OK.  Take the following
example (an excerpt from the client side of my SysV version of the GNU
client/server code)

  struct msgbuf *msgp = (struct msgbuf *)malloc(sizeof(struct msgbuf)+ 256);

  ......

  (void)strcpy(msgp->mtext,out);
  msgp->mtype = 1;
  if(msgsnd(msgqid,msgp,sizeof(struct msgbuf)+strlen(out)+1,1)==-1) 
    {
      perror("msg send ");
      exit(1);
    }

  .....

So anyway, I just allocate a message 256b + sizeof (msgbuf) long, then
use it again and again, by copying what I want to send into the
message, and sending it, specifying the size of what I want to send,
not the size of what I alloced.  This works well, and is a pretty
standard usage.


-- 

Paul Guthrie
ihnp4!ihdev!pdg			This Brain left intentionally blank.

rml@hpfcdc.UUCP (04/16/87)

> For structures allocated at run time, you can just "malloc" a block
> of memory containing "sizeof (int)" plus
> maximum-message-size-for-that-structure bytes and cast the resulting
> pointer to a pointer to a "struct msgbuf".

For maximum application portability it's probably safer to add
sizeof(struct msgbuf) than sizeof(int).  For one thing, mtype is a long,
not an int, in SVID (and implementations that I know of), so if anything
it should be sizeof(long) rather than sizeof(int); but that illustrates
a potential problem.  It's also possible that some machine would have
some strange alignment rules requiring padding between the long and the
array.  This also works for systems which choose to add extra fields to
the msgbuf structure ( such system would run into importability problems
as Guy points out, but it's safest for your code).

For the same reasons, this is safer than any of the mechanisms for
using static structures.

> So, anyone know the story??  This is not an isolated case, as both
> HP-UX (based on sys V) and even Sun's System V compatibility mode
> use this same definition (char mtext[1]).

For any vendor to do otherwise would reduce importability of code; there's
diminishing value in being N% System V compatible when N is less than 100.
There are lots of things most vendors (including AT&T) would change
about System V given freedom from compatibility issues.

		Bob Lenk
		{ihnp4, hplabs}!hpfcla!rml

Standard disclaimer: my opinions, not HP's.

coscilr@uhnix1.UUCP (09097) (04/28/87)

In article <419@artecon.artecon.UUCP> tony@artecon.artecon.UUCP (Anthony D. Parkhurst) writes:
>
>Question about System V message passing (IPC):
>
>In the man pages for msgop(2), it shows the message to be passed
>as type *msgbuf.  The man pages say the struct is:
>
>struct msgbuf{
>	int	mtype;	/* type of message (arbitrary) */
>	char	mtext[];	/* body of message */
>	}
>
>Now this implies that the pointer mtext can be assigned to an
>array or can be malloc'd to. (which makes sense)

Redefine msgbuf in your program instead of in the header file itself.  Use
 
  struct msgbuf1{
	int mtype;
	char mtext[100];
  }
for example.  The definition in the header file serves only as a template
which cannot be used directly.

Francis (CSNET: mkkam@houston.edu)