--- /dev/null
+/***************************************************************
+ *
+ * File wrappers.h: define a set of macro and inlined
+ * functions for signal, shared memory and semaphore handling
+ *
+ * Author: S. Piccardi
+ *
+ * $Id: wrappers.h,v 1.1 2001/03/05 22:20:08 piccardi Exp $
+ *
+ ***************************************************************/
+#include <sys/sem.h> /* IPC semaphore declarations */
+#include <sys/shm.h> /* IPC shared memory declarations */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h> /* signal handling declarations */
+/**
+ ** Semaphore definition; used to implement a MutexXXXX API
+ ** To create a Mutex use an underlaying semaphore and init it;
+ ** we put here all the needed data structires
+ **/
+/* put this definition, get from the man pages */
+#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
+ unsigned short int *array; /* array for GETALL, SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+#endif
+/*
+ * Define the sem_lock and sem_ulock sembuf structures to
+ * lock and unlock the semaphore (used to implement a mutex)
+ */
+struct sembuf sem_lock={ /* to lock semaphore */
+ 0, /* semaphore number (only one so 0) */
+ -1, /* semaphore operation (-1 to use resource) */
+ 0}; /* semaphore flag (in this case 0) */
+struct sembuf sem_ulock={ /* to unlock semaphore */
+ 0, /* semaphore number (only one so 0) */
+ 1, /* semaphore operation (-1 to release resource) */
+ 0}; /* semaphore flag (in this case 0) */
+/*
+ * Function MutexLock:
+ * to lock a mutex/semaphore
+ *
+ * Input: a semaphore id #
+ */
+inline void MutexLock(int sem_id)
+{
+ if (semop(sem_id,&sem_lock,1)) {
+ perror("Cannot lock the semaphore");
+ exit(1);
+ }
+}
+/*
+ * Function MutexUnlock
+ * to unlock a mutex/semaphore
+ *
+ * Input: a semaphore id #
+ */
+inline void MutexUnlock(int sem_id)
+{
+ if (semop(sem_id,&sem_ulock,1)) {
+ perror("Cannot unlock the semaphore");
+ exit(1);
+ }
+}
+/*
+ * Function MutexCreate:
+ * First call create a semaphore, using the given key.
+ * We want only one semaphore so we set second argument to 1; third
+ * parameter is the flag argument, and is set to create a semaphore
+ * with R/W privilege for the user.
+ * Second call initialize the semaphore to 1 (unlocked)
+ *
+ * Input: an IPC key value (to create an unique semaphore)
+ * Return: the semaphore id#
+ */
+const union semun semunion={1}; /* semaphore union structure */
+inline int MutexCreate(key_t ipc_key)
+{
+ int sem_id;
+ if( (sem_id=semget(ipc_key,1,IPC_CREAT|0666))<0 ){ /* get sem ID */
+ perror("cannot create semaphore"); /* a sem_id <0 is an error */
+ printf("semid=%d",sem_id);
+ exit(1);
+ }
+ if ( (semctl(sem_id,0,SETVAL,semunion)) < 0 ) {
+ perror("cannot init semaphore"); /* <0 is an error */
+ printf("on semid=%d",sem_id);
+ exit(1);
+ }
+ return sem_id;
+}
+/*
+ * Find Mutex
+ * get the semaphore/mutex Id given the IPC key value
+ *
+ * Input: an IPC key value
+ */
+inline int MutexFind(key_t ipc_key)
+{
+ int sem_id;
+ if( (sem_id=semget(ipc_key,1,0))<0 ){ /* find sem .ID */
+ perror("cannot find semaphore");
+ exit(1);
+ }
+ return sem_id;
+}
+/*
+ * Function MutexRead:
+ * Read the current value of the mutex/semaphore
+ *
+ * Input: a semaphore id #
+ * Return: the semaphore value
+ */
+inline int MutexRead(int sem_id)
+{
+ int value;
+ if ( (value=semctl(sem_id,0,GETVAL,semunion)) < 0 ) {
+ perror("cannot read semaphore"); /* a <0 is an error */
+ printf("on semid=%d\n",sem_id);
+ exit(1);
+ }
+ return value;
+}
+/*
+ * Function ShmCreate:
+ * Allocate a shared memory segment.
+ * First call get a shared memory segment with KEY key access and size SIZE,
+ * by creating it with R/W privilege for the user (this is the meaning of
+ * the ored flags). The function return an identifier shmid used for any
+ * further reference to the shared memory segment.
+ * Second call attach the shared memory segment to this process and return a
+ * pointer to it (of char * type).
+ * Then initialize shared memory:
+ * Set all to 0x55 (means 0101 un binary notation
+ *
+ * Input: an IPC key value
+ * the shared memory segment size
+ * Return: the address of the segment
+ */
+inline char * ShmCreate(key_t ipc_key, int shm_size)
+{
+ char * shptr;
+ int shmid; /* ID of the IPC shared memory segment */
+ if ((shmid=shmget(ipc_key,shm_size,IPC_CREAT|0666))<0){ /* get shm ID */
+ perror("cannot find shared memory");
+ exit(1);
+ }
+ if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
+ perror("cannot attach shared memory");
+ exit(1);
+ }
+ memset((void *)shptr,0x55,shm_size); /* second couter starts from "0" */
+ return shptr;
+}
+/*
+ * Function ShmFind:
+ * Find a shared memory segment
+ * Input: an IPC key value
+ * the shared memory segment size
+ * Return: the address of the segment
+ */
+inline char * ShmFind(key_t ipc_key, int shm_size)
+{
+ char * shptr;
+ int shmid; /* ID of the IPC shared memory segment */
+ if ( (shmid=shmget(ipc_key,shm_size,0))<0 ){ /* find shared memory ID */
+ perror("cannot find shared memory");
+ exit(1);
+ }
+ if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */
+ perror("cannot attach shared memory");
+ exit(1);
+ }
+ return shptr;
+}
+/*
+ * Function LockFile:
+ * Create a lockfile of the given pathname.
+ * Fail and exit in case of error or existence of the same lock
+ * file, using unlink do not need to remove the file,
+ */
+inline void LockFile(const char* path_name)
+{
+ if (open(path_name, O_EXCL|O_CREAT)<0) {
+ perror("Already active");
+ exit(1);
+ }
+}
+inline void UnlockFile(const char* path_name)
+{
+ if (unlink(path_name)) {
+ perror("error, cannot unlink");
+ exit(1);
+ }
+}
+/*
+ * Function Signal
+ * Initialize a signal handler.
+ * To enable the signal handling a process we need to tell it to
+ * kernel; this is done writing all needed info to a sigaction structure
+ * named sigact, and then callind sigaction() system call passing the
+ * information stored in the sigact structure variable.
+ *
+ * Input: the signal to handle
+ * the signal handler function
+ * Return: the previous sigaction structure
+ */
+typedef void SigFunc(int);
+SigFunc * Signal(int signo, SigFunc *func)
+{
+ struct sigaction new_handl, old_handl;
+ new_handl.sa_handler=func;
+ /* clear signal mask: no signal blocked during execution of func */
+ if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */
+ perror("cannot initializes the signal set to empty"); /* see mess. */
+ exit(1);
+ }
+ new_handl.sa_flags=0; /* init to 0 all flags */
+ /* change action for signo signal */
+ if (sigaction(signo,&new_handl,&old_handl)){
+ perror("sigaction failed on signal action setting");
+ exit(1);
+ }
+ return (old_handl.sa_handler);
+}
+