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.4 2002/11/20 23:34:02 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 * Function MutexCreate: create a mutex/semaphore
37 * First call create a semaphore, using the given key.
38 * We want only one semaphore so we set second argument to 1; third
39 * parameter is the flag argument, and is set to create a semaphore
40 * with R/W privilege for the user.
41 * Second call initialize the semaphore to 1 (unlocked)
43 * Input: an IPC key value (to create an unique semaphore)
44 * Return: the semaphore id# or -1 on error
46 inline int MutexCreate(key_t ipc_key)
48 const union semun semunion={1}; /* semaphore union structure */
50 sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */
51 if (sem_id == -1) { /* if error return code */
54 ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */
61 * Function MutexFind: get the semaphore/mutex Id given the IPC key value
63 * Input: an IPC key value
65 inline int MutexFind(key_t ipc_key)
67 return semget(ipc_key,1,0);
70 * Function MutexRead: read the current value of the mutex/semaphore
72 * Input: a semaphore id #
73 * Return: the semaphore value
75 inline int MutexRead(int sem_id)
77 return semctl(sem_id, 0, GETVAL);
80 * Define sembuf structures to lock and unlock the semaphore
81 * (used to implement a mutex)
83 struct sembuf sem_lock={ /* to lock semaphore */
84 0, /* semaphore number (only one so 0) */
85 -1, /* operation (-1 to use resource) */
86 SEM_UNDO}; /* flag (set for undo at exit) */
87 struct sembuf sem_ulock={ /* to unlock semaphore */
88 0, /* semaphore number (only one so 0) */
89 1, /* operation (1 to release resource) */
90 SEM_UNO}; /* flag (in this case 0) */
92 * Function MutexLock: to lock a mutex/semaphore
94 * Input: a semaphore id #
95 * Output: semop return code (0 OK, -1 KO)
97 inline int MutexLock(int sem_id)
99 return semop(sem_id, &sem_lock, 1);
102 * Function MutexUnlock: to unlock a mutex/semaphore
104 * Input: a semaphore id #
105 * Return: semop return code (0 OK, -1 KO)
107 inline int MutexUnlock(int sem_id)
109 return semop(sem_id, &sem_ulock, 1);
112 * Function ShmCreate:
113 * Allocate a shared memory segment.
114 * First call get a shared memory segment with KEY key access and size SIZE,
115 * by creating it with R/W privilege for the user (this is the meaning of
116 * the ored flags). The function return an identifier shmid used for any
117 * further reference to the shared memory segment.
118 * Second call attach the shared memory segment to this process and return a
119 * pointer to it (of char * type).
120 * Then initialize shared memory:
121 * Set all to 0x55 (means 0101 un binary notation
123 * Input: an IPC key value
124 * the shared memory segment size
125 * Return: the address of the segment
127 inline char * ShmCreate(key_t ipc_key, int shm_size)
130 int shmid; /* ID of the IPC shared memory segment */
131 if ((shmid=shmget(ipc_key,shm_size,IPC_CREAT|0666))<0){ /* get shm ID */
132 perror("cannot find shared memory");
135 if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
136 perror("cannot attach shared memory");
139 memset((void *)shptr,0x55,shm_size); /* second couter starts from "0" */
144 * Find a shared memory segment
145 * Input: an IPC key value
146 * the shared memory segment size
147 * Return: the address of the segment
149 inline char * ShmFind(key_t ipc_key, int shm_size)
152 int shmid; /* ID of the IPC shared memory segment */
153 if ( (shmid=shmget(ipc_key,shm_size,0))<0 ){ /* find shared memory ID */
154 perror("cannot find shared memory");
157 if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
158 perror("cannot attach shared memory");
165 * Create a lockfile of the given pathname.
166 * Fail and exit in case of error or existence of the same lock
167 * file, using unlink do not need to remove the file,
169 inline void LockFile(const char* path_name)
171 if (open(path_name, O_EXCL|O_CREAT)<0) {
172 perror("Already active");
176 inline void UnlockFile(const char* path_name)
178 if (unlink(path_name)) {
179 perror("error, cannot unlink");
185 * Initialize a signal handler.
186 * To enable the signal handling a process we need to tell it to
187 * kernel; this is done writing all needed info to a sigaction structure
188 * named sigact, and then callind sigaction() system call passing the
189 * information stored in the sigact structure variable.
191 * Input: the signal to handle
192 * the signal handler function
193 * Return: the previous sigaction structure
195 typedef void SigFunc(int);
196 inline SigFunc * Signal(int signo, SigFunc *func)
198 struct sigaction new_handl, old_handl;
199 new_handl.sa_handler=func;
200 /* clear signal mask: no signal blocked during execution of func */
201 if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
202 perror("cannot initializes the signal set to empty"); /* see mess. */
205 new_handl.sa_flags=0; /* init to 0 all flags */
206 /* change action for signo signal */
207 if (sigaction(signo,&new_handl,&old_handl)){
208 perror("sigaction failed on signal action setting");
211 return (old_handl.sa_handler);
215 ** Defining prototypes for the all other functions
217 ssize_t SockRead(int fd, void *buf, size_t count);
218 ssize_t SockWrite(int fd, const void *buf, size_t count);
220 void HandSIGCHLD(int sig);