EE784@sscvax.mcmaster.ca (05/11/88)
In answering another query in this newsgroup, I got to thinking about how I'd interpreted the original documentation for a return value from one of the shared memory functions. Presumably there are: 1) others who have also thought about this question; 2) others who know the answer. Under uPort sysV/AT (a system V, rev. 2 port to IBM AT and clones [swapping, not paging:-) ]) shared memory is supported for, among other things, using the memory-mapped video RAM. The man pages for the various shm(2) calls give the following synopses: int shmid ( key, size, shmflg ) key_t key; int size, shmflg; char *shmat ( shmid, shmaddr, shmflg ) int shmid; char *shmaddr; int shmflg; [stuff about detaching deleted] and say the following about the return value of shmat: Upon successful completion, the return value is as follows: Shmat returns the data segment start address of the attached shared memory segment. [stuff about detaching deleted] Otherwise, a value of -1 is returned and errno is set to indicate the error. Since shared memory is available only under the large model, pointers are 32 bits. There is no apparent reason that a pointer cannot assume the equivalent of -1 for valid addresses (although trying to use it will probably generate a memory exception, since I certainly don't have that much physical memory). My initial temptation was to assume the documentation was wrong and that a NULL pointer should be returned if shmat fails; however, the doc'n went out of its way to indicate that it should be -1 (presumably -1L) on failure. So the code that uses it looks like: int gfx_id, shmget (); unsigned g_plane_siz = 32768U; char *gfx_ptr, *shmat (); key_t gfx_key; if (( gfx_id = shmget ( gfx_key, g_plane_siz, 0 )) == -1 ) { perror (); exit ( 1 ); } gfx_ptr = shmat ( gfx_id, (char *)NULL, 0 ); if ( (long)gfx_ptr == -1L ) { perror (); exit ( 1 ); } The original key is assigned at boot time to make the graphics memory public, and shmflg (== 0) is effectively ignored. So, the code works, and there is no good reason why the attach should fail if the key is available, but I've always been bothered about the test on gfx_ptr. The other obvious anomaly here is that the documentation indicates that g_plane_siz must be int, but uPort's own examples assume it is unsigned, and this in fact works. So, the questions are: 1) what is the proper return value of shmat on failure; 2) if it is -1, is it int or long (should be long, I believe). Any other insights cheerfully accepted. --mike borza <EE784.SSCvax.McMaster.CA>
Ed@mead.scrc.symbolics.com (Ed Schwalenberg) (05/14/88)
Date: Wed, 11 May 88 01:50 EST From: EE784@sscvax.mcmaster.ca Under uPort sysV/AT (a system V, rev. 2 port to IBM AT and clones [swapping, not paging:-) ]) shared memory is supported for, among other things, using the memory-mapped video RAM. The man pages for the various shm(2) calls give the following synopses: ... and say the following about the return value of shmat: Upon successful completion, the return value is as follows: Shmat returns the data segment start address of the attached shared memory segment. [stuff about detaching deleted] Otherwise, a value of -1 is returned and errno is set to indicate the error. Since shared memory is available only under the large model, pointers are 32 bits. There is no apparent reason that a pointer cannot assume the equivalent of -1 for valid addresses (although trying to use it will probably generate a memory exception, since I certainly don't have that much physical memory). My initial temptation was to assume the documentation was wrong and that a NULL pointer should be returned if shmat fails; however, the doc'n went out of its way to indicate that it should be -1 (presumably -1L) on failure. So, the questions are: 1) what is the proper return value of shmat on failure; At least in the AT&T/Intel/Interactive System V for the 386, you can only attach shared memory segments on 4Meg boundaries. NULL is on a 4Meg boundary, but -1 is not. Normally, of course, your text segment lives at 0, but perhaps you can make an executable with the text segment elsewhere, and use segment 0 for shared memory. 2) if it is -1, is it int or long (should be long, I believe). Any other insights cheerfully accepted. --mike borza <EE784.SSCvax.McMaster.CA>
mike@cimcor.UUCP (Michael Grenier) (05/15/88)
From article <14379@brl-adm.ARPA>, by Ed@mead.scrc.symbolics.com (Ed Schwalenberg): > Under uPort sysV/AT (a system V, rev. 2 port to IBM AT and clones [swapping, > not paging:-) ]) shared memory is supported for, among other things, using > the memory-mapped video RAM. ... > much physical memory). My initial temptation was to assume the > documentation was wrong and that a NULL pointer should be returned if > shmat fails; however, the doc'n went out of its way to indicate that it > should be -1 (presumably -1L) on failure. > > So, the questions are: > 1) what is the proper return value of shmat on failure; This is what my graphics package does under Microport Unix V/AT for the shared memory attach. Using a cast you don't worry if its long or not. -Mike Grenier {ihnp4, rutgers, amdahl}!bungia!cimcor!mike void g_herc_open() { if ((shm_id = shmget ((key_t)Herc_loc, SCREEN_SIZE*2L-1 , 0)) == -1) { perror(" gplot:herc_open() - "); fprintf(stderr, "Unable to locate shared memory segment \n"); fprintf(stderr, "Did you execute /etc/shmcreate as found in /etc/rc.d/shm.rc \n"); fprintf(stderr, "i.e. /etc/shmcreate 0xb0000 b0000 32768\n"); exit(1); }; if ((video_buf = shmat (shm_id, (char *) 0, 0)) == (char *) -1) { perror(" gplot:herc_open() - "); fprintf(stderr, "Unable to attach shared memory segment \n"); fprintf(stderr, "Did you execute /etc/shmcreate as found in /etc/rc.d/shm.rc \n"); exit(1); }; init_io(); }
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (05/17/88)
I think this is a major conflict with ANSI C. The procedure must return either an int or a pointer, but it can't portably do both, since some systems don't represent the two types remotely the same way. This works on the nice machine on which SysV was developed, but you better hope that what's really returned for an error is "(char *) -1". -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/17/88)
In article <10861@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > I think this is a major conflict with ANSI C. The procedure must >return either an int or a pointer, but it can't portably do both, since >some systems don't represent the two types remotely the same way. This >works on the nice machine on which SysV was developed, but you better >hope that what's really returned for an error is "(char *) -1". This botch has nothing to do with ANSI C. A lot of old UNIX code (mostly inherited from PDP-11-only days) did not properly distinguish between integers and pointers. Due to the way the system call error handling routine worked, functions such as sbrk() returned some form of -1, perhaps ((char *)-1), on error. Obviously the proper C design for such error returns (reported in-band in a nominally pointer value) would be a null pointer, not some sort of cast -1. Why this wasn't fixed when the IPC stuff was added for USG 4.x I don't know. Probably the same reason the PWB/Graphics unportable uses of getc() were "fixed" by adding #if u3b2 instead of doing it right.