1 /***************************************************************
3 * File wrappers.h: define a set of macro and inlined
4 * functions for signal, shared memory and semaphore handling
8 * $Id: wrappers.h,v 1.2 2001/06/10 11:47:17 piccardi Exp $
10 ***************************************************************/
11 #include <sys/sem.h> /* IPC semaphore declarations */
12 #include <sys/shm.h> /* IPC shared memory declarations */
13 #include <sys/types.h>
16 #include <signal.h> /* signal handling declarations */
18 ** Semaphore definition; used to implement a MutexXXXX API
19 ** To create a Mutex use an underlaying semaphore and init it;
20 ** we put here all the needed data structires
22 /* put this definition, get from the man pages */
23 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
24 /* union semun is defined by including <sys/sem.h> */
26 /* according to X/OPEN we have to define it ourselves */
28 int val; /* value for SETVAL */
29 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
30 unsigned short int *array; /* array for GETALL, SETALL */
31 struct seminfo *__buf; /* buffer for IPC_INFO */
35 * Define the sem_lock and sem_ulock sembuf structures to
36 * lock and unlock the semaphore (used to implement a mutex)
38 struct sembuf sem_lock={ /* to lock semaphore */
39 0, /* semaphore number (only one so 0) */
40 -1, /* semaphore operation (-1 to use resource) */
41 0}; /* semaphore flag (in this case 0) */
42 struct sembuf sem_ulock={ /* to unlock semaphore */
43 0, /* semaphore number (only one so 0) */
44 1, /* semaphore operation (-1 to release resource) */
45 0}; /* semaphore flag (in this case 0) */
48 * to lock a mutex/semaphore
50 * Input: a semaphore id #
52 inline void MutexLock(int sem_id)
54 if (semop(sem_id,&sem_lock,1)) {
55 perror("Cannot lock the semaphore");
60 * Function MutexUnlock
61 * to unlock a mutex/semaphore
63 * Input: a semaphore id #
65 inline void MutexUnlock(int sem_id)
67 if (semop(sem_id,&sem_ulock,1)) {
68 perror("Cannot unlock the semaphore");
73 * Function MutexCreate:
74 * First call create a semaphore, using the given key.
75 * We want only one semaphore so we set second argument to 1; third
76 * parameter is the flag argument, and is set to create a semaphore
77 * with R/W privilege for the user.
78 * Second call initialize the semaphore to 1 (unlocked)
80 * Input: an IPC key value (to create an unique semaphore)
81 * Return: the semaphore id#
83 const union semun semunion={1}; /* semaphore union structure */
84 inline int MutexCreate(key_t ipc_key)
87 if( (sem_id=semget(ipc_key,1,IPC_CREAT|0666))<0 ){ /* get sem ID */
88 perror("cannot create semaphore"); /* a sem_id <0 is an error */
89 printf("semid=%d",sem_id);
92 if ( (semctl(sem_id,0,SETVAL,semunion)) < 0 ) {
93 perror("cannot init semaphore"); /* <0 is an error */
94 printf("on semid=%d",sem_id);
101 * get the semaphore/mutex Id given the IPC key value
103 * Input: an IPC key value
105 inline int MutexFind(key_t ipc_key)
108 if( (sem_id=semget(ipc_key,1,0))<0 ){ /* find sem .ID */
109 perror("cannot find semaphore");
115 * Function MutexRead:
116 * Read the current value of the mutex/semaphore
118 * Input: a semaphore id #
119 * Return: the semaphore value
121 inline int MutexRead(int sem_id)
124 if ( (value=semctl(sem_id,0,GETVAL,semunion)) < 0 ) {
125 perror("cannot read semaphore"); /* a <0 is an error */
126 printf("on semid=%d\n",sem_id);
132 * Function ShmCreate:
133 * Allocate a shared memory segment.
134 * First call get a shared memory segment with KEY key access and size SIZE,
135 * by creating it with R/W privilege for the user (this is the meaning of
136 * the ored flags). The function return an identifier shmid used for any
137 * further reference to the shared memory segment.
138 * Second call attach the shared memory segment to this process and return a
139 * pointer to it (of char * type).
140 * Then initialize shared memory:
141 * Set all to 0x55 (means 0101 un binary notation
143 * Input: an IPC key value
144 * the shared memory segment size
145 * Return: the address of the segment
147 inline char * ShmCreate(key_t ipc_key, int shm_size)
150 int shmid; /* ID of the IPC shared memory segment */
151 if ((shmid=shmget(ipc_key,shm_size,IPC_CREAT|0666))<0){ /* get shm ID */
152 perror("cannot find shared memory");
155 if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
156 perror("cannot attach shared memory");
159 memset((void *)shptr,0x55,shm_size); /* second couter starts from "0" */
164 * Find a shared memory segment
165 * Input: an IPC key value
166 * the shared memory segment size
167 * Return: the address of the segment
169 inline char * ShmFind(key_t ipc_key, int shm_size)
172 int shmid; /* ID of the IPC shared memory segment */
173 if ( (shmid=shmget(ipc_key,shm_size,0))<0 ){ /* find shared memory ID */
174 perror("cannot find shared memory");
177 if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
178 perror("cannot attach shared memory");
185 * Create a lockfile of the given pathname.
186 * Fail and exit in case of error or existence of the same lock
187 * file, using unlink do not need to remove the file,
189 inline void LockFile(const char* path_name)
191 if (open(path_name, O_EXCL|O_CREAT)<0) {
192 perror("Already active");
196 inline void UnlockFile(const char* path_name)
198 if (unlink(path_name)) {
199 perror("error, cannot unlink");
205 * Initialize a signal handler.
206 * To enable the signal handling a process we need to tell it to
207 * kernel; this is done writing all needed info to a sigaction structure
208 * named sigact, and then callind sigaction() system call passing the
209 * information stored in the sigact structure variable.
211 * Input: the signal to handle
212 * the signal handler function
213 * Return: the previous sigaction structure
215 typedef void SigFunc(int);
216 inline SigFunc * Signal(int signo, SigFunc *func)
218 struct sigaction new_handl, old_handl;
219 new_handl.sa_handler=func;
220 /* clear signal mask: no signal blocked during execution of func */
221 if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
222 perror("cannot initializes the signal set to empty"); /* see mess. */
225 new_handl.sa_flags=0; /* init to 0 all flags */
226 /* change action for signo signal */
227 if (sigaction(signo,&new_handl,&old_handl)){
228 perror("sigaction failed on signal action setting");
231 return (old_handl.sa_handler);
235 ** Defining prototypes for the all other functions
237 ssize_t SockRead(int fd, void *buf, size_t count);
238 ssize_t SockWrite(int fd, const void *buf, size_t count);