X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2Fwrappers.h;fp=sources%2Fwrappers.h;h=70eb402240b2f6fdca8af8328ddad7f689d30ffc;hp=0000000000000000000000000000000000000000;hb=3d44c36183fe67ed64bff95a36596ad87f620683;hpb=d05c744fc23f1ba7ec85c8268abdc8ee8426d950 diff --git a/sources/wrappers.h b/sources/wrappers.h new file mode 100644 index 0000000..70eb402 --- /dev/null +++ b/sources/wrappers.h @@ -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 /* IPC semaphore declarations */ +#include /* IPC shared memory declarations */ +#include +#include +#include +#include /* 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 */ +#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); +} +