chad@lakesys.UUCP (D. Chadwick Gibbons) (02/06/89)
I am having some problems with shared memory operations on SCO XENIX/286 2.2.3 - System V shared memory, not the Xenix equivalent. On a 286 you have to declare the shared memory segment to be a pointer to a far segment of memory. Unless you use large model programs, you have to write your own versions of standard library functions which will access the segment. The example given in the manual is that of strcpy(), which will copy a given string into the segment. It is identical to the standard library's version, except the first argument is declared as a far character pointer. On the application I am presently working on I use the shared segment as a table for multiple users to access. I define the segment's size as a "sizeof(struct shmem);" which is the structure containing the process table. The main accessing of the shared segment is done through two functions, putmem(), and getmem() which preform as memcpy() would except modified to handle the far pointer. Here is the code for putmem(): /* putmem: places data into shared memory segment */ void putmem(mem) struct shmem *mem; { register char far *d; register char *s; register int n; int size; size = sizeof(mem); if (size <= 0) return; s = (char *)mem; d = Memory; if (s <= d && s + (size - 1) >= d) { /* overlap, must copy right-to-left */ s += size - 1; d += size - 1; for (n = size; n > 0; n--) *d-- = *s--; } else for (n = size; n > 0; n--) *d++ = *s++; return; } The global "Memory" is simply the shared memory segment. It is defined as "char far *Memory;" and is initilized by another function which attaches the given process to the shared segment. The "register" identifier on the variable "d" is probably illused. I don't believe a far pointer can be placed in a register - at least the compiler listing (-Fs option) does not list it as being in a register. However, removing the register declaration does not change my error. In the beginning of the application, the shared segment is attached to, and the creating process attempts to place a empty structure in the segment. The structure contains information such as empty strings and -1 for integers and this is my way of telling other processes that a given location is unused. When I attempt to call putmem(); I receive a memory fault from this function. The debugger reports it occurs with this line: "*d++ = *s++;" which is where the copying of the data is being preformed. What am I doing wrong with the copy of the data? I would think this should work, but, of course, it doesn't. I tried using memcpy() but it did not work due to the far pointer. Any information would be appreciated, as always. My logic for the code of this function was obtained from using a public domain version of memcpy(). -- D. Chadwick Gibbons, chad@lakesys.lakesys.com, ...!uunet!marque!lakesys!chad