Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site psivax.UUCP Path: utzoo!watmath!clyde!cbosgd!ukma!psuvm.bitnet!psuvax1!burdvax!sdcrdcf!psivax!friesen From: friesen@psivax.UUCP (Stanley Friesen) Newsgroups: net.unix Subject: Re: Sys V IPC: My final word Message-ID: <1009@psivax.UUCP> Date: Thu, 13-Feb-86 11:48:11 EST Article-I.D.: psivax.1009 Posted: Thu Feb 13 11:48:11 1986 Date-Received: Sat, 15-Feb-86 06:23:30 EST References: <2666@gatech.CSNET> Reply-To: friesen@psiluvu.UUCP (Stanley Friesen) Organization: Pacesetter Systems Inc., Sylmar, CA Lines: 46 Keywords: ipc, msg In article <2666@gatech.CSNET> hope@gatech.CSNET (Theodore Hope) writes: > >This kind of struc, especially in a syscall-passing sense, seems odd to me. >It is obvious that mtext should be > > char mtext [some_number]; > >"Oh," said I. "I'll bet that's a misprint. Let's look at the >file to see what they _really_ mean." Well, surprise. The .h file defines > > struct msgbuf { > long mtype; > char mtext [1]; <- Notice: it says [1] > } > >Am I overlooking something obvious? After looking through the kernel source, >it appeared that the msgsnd and msgrcv syscalls expect the data to start at >msg.mtext, > Well, it really isn't that obvious. The man page is *not* a misprint, and the .h file is "correct" also. What is happening here is a rather tricky piece of "C" coding to permit *variable* sized arrays to be passed without allocating all the space necessary for the maximum size, and without any real maximum size. Basically it is taking advantage of the fact that "C" doesn't check array subscripts and the way in which address calculation is done. Basically the declared array in the struct is only being used as the *base* of the array. Subscripting off that base will access succesively higher addresses, so that a unit "array" at the end of a struct can effectively be extended indefinately, merely by allocating space at the end of it. The way this is intended to be used is struct msgbuf *msgptr; msgptr = (struct msgbuf *)malloc(sizeof(struct msgbuf) + sizeof(message)); This way your msgbuf exactly matches the size of your message. Yeah, I know, a really obscure trick. I know about it because it is also used in the game Hack. -- Sarima (Stanley Friesen) UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen ARPA: ttidca!psivax!friesen@rand-unix.arpa