/* sem.c -- semaphores and shared memory routines (c) 1989, 1994, Howard E. Motteler NAME: sem.c -- semaphores and shared memory routines SYNOPSIS: This set of routines creates both a set of NSEM semaphores and SBYTES of shared memory, to be used by a set of communicating processes. sinit() initialize or attach to semaphores and shared memory sclear() delete semaphore set and shared memory ssig(s) signal semaphore s swait(s) wait on semaphore s stest(s) returns the value of semaphore s showall() prints out all semaphores sbase() returns a char pointer to the shared memory block DESCRIPTION: Semaphores are indexed by integers, in the range 0 to NSEM-1; thus for example ssig(3) signals on semaphore number 3. Semaphores stay set when a process exits normally. You can change this behavior by setting SEM_UNDO in ssig() and swait(), but you probably don't want to do that. You can have more than one process waiting on a semaphore, and wake them 1 at a time with signals, but the "wake order" is not specified (at least not by me). The first call to sinit() actually creates the semaphores and shared memory regions, and subsequent calls simply "attach" to them. All processes that want to use semaphores or shared memory should call sinit() once, before any semaphore or shared memory operations are performed. The sclear() routine deletes the semaphore and shared memory blocks. It should be called whenever the last process in a group of communication processes finishes normally. It can also be called from a separate program. If you do not use sclear(), old values can remain in semaphores. Also, semaphores are a finite resource. If too many users forget to call sclear(), the system can run out of semaphores, as they stay allocated even when you log out. If any processes are doing an swait() when sclear is called they will terminate with an error message of the form "Process nn semop error on swait()." When any process that calls sinit() receives a Unix signal such as ^C or KILL, it calls a routine sigclear() that deletes the semaphore and shared memory blocks, and prints a message of the form "Process nnn terminated on unix signal." An ^C or KILL may generate a mixture of termination and semop error messages. */ #include #include #include #include #include #define NSEM 16 /* number of semaphores */ #define SBYTES 16384 /* size of shared memory block */ #define DEBUG 0 /* non-zero gives error messages */ #define SPROT 0600 /* sem/shmem protection flags */ int shmid; /* user's shared memory id */ int semid; /* user's semaphore id */ char *shmaddr; /* pointer to shared memory */ /* Initialize or attach to semaphores and shared memory region */ void sinit() { int i, pid; key_t shmkey; /* sys V shared memory key */ key_t semkey; /* sys V semaphore key */ short outarray[NSEM]; /* extern void *shmat(); */ extern void sigtrap(); pid = getpid(); for (i=0; i