[] Creation
o union semun arguments;
o key_t key = 1;
o int flags = 0777 | IPC_CREAT;
o int semid = semget(key, 1, flags);
o argument.val = initialvalue;
o semctl(semid, 0, SETVAL, argument);
[] Destruction
o int ignored_int;
o union semun ignored;
o semctl(semid, ignored_int, IPC_RMID, ignored);
I wanted to create an array of two semaphores, so I wrote the follow-
ing <main> function:
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
...
int main ( int argCount
, char** arguments)
{
pthread_t Write[ 2];
union semun argument; <=================
key_t key = 1;
int flags = 0700 | IPC_CREAT;
int before[ 2];
int pairs[ 2][ 2];
int result;
int parity;
int end;
printf( "Before creation of semaphores.\n");
for (parity = EVEN; parity <= ODD; parity++)
{ before[ parity] = semget( key, 1, flags);
argument.val = parity;
semctl( before[ parity], 0, SETVAL, argument);
}
...
But when I try to compile it I get the error message
"CountSharer.c:44: error: storage size of 'argument' isn't known".
Line 44 is the line my arrow is pointing to up above. The slide up
above is the only reference to <union semun> that I know of. Does
anyone know what I need to do to my <argument> variable to keep this
error from occurring?
---Kevin Simonson
"You'll never get to heaven, or even to LA,
if you don't believe there's a way."
from _Why Not_
You will need either a good book or access to manual pages. On my
system "man semctl" tells me:
"The calling program must define this union as follows:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};"
so it is up to you to define this union when you want to use those
features of semctl (those that require a fourth argument). Your local
system may require something else, but the manual pages should tell you.
--
Ben.
Bye Jojo
The prototype of the function semctl is
int semctl (int __semid, int __semnum, int __cmd, ...);
I have the nasty suspicion that the union was introduced into the
man-page as a semi-formal way of declaring that the fourth parameter
could be either an int or one of three pointer types but wasn't actually
intended to be used as a union. On most unix systems it doesn't make a
difference whether you call
semctl (sem_id, 0, SETVAL, 15);
or
union semun su;
su.val = 15;
semctl (sem_id, 0, SETVAL, su);
resp.
struct semid_ds ds;
semctl (sem_id, 0, SETVAL, &ds);
or
union semun su;
su.buf = &ds;
semctl (sem_id, 0, SETVAL, su);
either because int and pointers are the same size or because at least
the first 4 parameters are passed in registers.
As further evidence for this suspicion I cite the OSF/1 man-page for
semctl (ca. 1992), which declares the union as:
union semun {
int val;
struct semun *buf;
ushort array[];
};
which isn't even legal C, and if the DEC C compiler supported array[] as
an extension (many compilers at that time did) the semantics would not
have been the same as that of ushort *array (which was obviously
intended).
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | h...@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"