Funzione di creazione e ricerca del mutex
[gapil.git] / sources / wrappers.h
1 /***************************************************************
2  *
3  * File wrappers.h: define a set of macro and inlined 
4  * functions for signal, shared memory and semaphore handling
5  *
6  * Author: S. Piccardi
7  *
8  * $Id: wrappers.h,v 1.3 2002/08/18 23:24:44 piccardi Exp $
9  *
10  ***************************************************************/
11 #include <sys/sem.h>     /* IPC semaphore declarations */
12 #include <sys/shm.h>     /* IPC shared memory declarations */
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <signal.h>      /* signal handling declarations */
17 /**
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
21  **/
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> */
25 #else
26 /* according to X/OPEN we have to define it ourselves */
27 union semun {
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 */
32 };
33 #endif
34 /*
35  * Define the sem_lock and sem_ulock sembuf structures to 
36  * lock and unlock the semaphore (used to implement a mutex)
37  */
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) */
46 /*
47  * Function MutexLock:
48  * to lock a mutex/semaphore
49  *
50  * Input: a semaphore id #
51  */
52 inline void MutexLock(int sem_id) 
53 {
54     if (semop(sem_id,&sem_lock,1)) {
55         perror("Cannot lock the semaphore");
56         exit(1);
57     }
58 }
59 /*
60  * Function MutexUnlock
61  * to unlock a mutex/semaphore
62  *
63  * Input: a semaphore id #
64  */
65 inline void MutexUnlock(int sem_id) 
66 {
67     if (semop(sem_id,&sem_ulock,1)) {
68         perror("Cannot unlock the semaphore");
69         exit(1);
70     }
71 }
72 /*
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)
79  *
80  * Input: an IPC key value (to create an unique semaphore)
81  * Return: the semaphore id#
82  */
83 const union semun semunion={1};    /* semaphore union structure */
84 inline int MutexCreate(key_t ipc_key) 
85 {
86     int sem_id;
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);
90         exit(1);
91     }
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);
95         exit(1);
96     }
97     return sem_id;
98 }
99 /*
100  * Find Mutex
101  * get the semaphore/mutex Id given the IPC key value
102  *
103  * Input: an IPC key value
104  */
105 inline int MutexFind(key_t ipc_key) 
106 {
107     int sem_id;
108     if( (sem_id=semget(ipc_key,1,0))<0 ){       /* find sem .ID */
109         perror("cannot find semaphore");
110         exit(1);
111     }
112     return sem_id;
113 }
114 /*
115  * Function MutexRead:
116  * Read the current value of the mutex/semaphore
117  *
118  * Input:  a semaphore id #
119  * Return: the semaphore value
120  */
121 inline int MutexRead(int sem_id) 
122 {
123     int value;
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);
127               exit(1);
128     } 
129     return value;
130 }
131 /*
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
142  *
143  * Input:  an IPC key value
144  *         the shared memory segment size
145  * Return: the address of the segment
146  */
147 inline char * ShmCreate(key_t ipc_key, int shm_size) 
148 {
149     char * shptr;
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");
153         exit(1);
154     }
155     if ( (shptr=shmat(shmid,0,0)) < 0 ){    /* take the pointer to it */
156         perror("cannot attach shared memory");
157         exit(1);
158     }
159     memset((void *)shptr,0x55,shm_size);  /* second couter starts from "0" */
160     return shptr;
161 }
162 /*
163  * Function ShmFind:
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
168  */
169 inline char * ShmFind(key_t ipc_key, int shm_size) 
170 {
171     char * shptr;
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");
175         exit(1);
176     }
177     if ( (shptr=shmat(shmid,0,0)) < 0 ){    /* take the pointer to it */
178         perror("cannot attach shared memory");
179         exit(1);
180     }
181     return shptr;
182 }
183 /*
184  * Function LockFile:
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,
188  */
189 inline void LockFile(const char* path_name) 
190 {
191     if (open(path_name, O_EXCL|O_CREAT)<0) {
192         perror("Already active");
193         exit(1);
194     } 
195 }
196 inline void UnlockFile(const char* path_name) 
197 {
198     if (unlink(path_name)) {
199         perror("error, cannot unlink");
200         exit(1);
201     }   
202 }
203 /*
204  * Function Signal
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.
210  *
211  * Input:  the signal to handle 
212  *         the signal handler function
213  * Return: the previous sigaction structure
214  */
215 typedef void SigFunc(int);
216 inline SigFunc * Signal(int signo, SigFunc *func) 
217 {
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. */
223         exit(1);
224     }
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");
229         exit(1);
230     }
231     return (old_handl.sa_handler);
232 }
233
234 /**
235  ** Defining prototypes for the all other functions
236  **/ 
237 ssize_t SockRead(int fd, void *buf, size_t count);
238 ssize_t SockWrite(int fd, const void *buf, size_t count);
239
240 void HandSIGCHLD(int sig);