Initial revision
[gapil.git] / sources / wrappers.h
diff --git a/sources/wrappers.h b/sources/wrappers.h
new file mode 100644 (file)
index 0000000..70eb402
--- /dev/null
@@ -0,0 +1,233 @@
+/***************************************************************
+ *
+ * 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);
+}
+