//**************************************************************************
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
//**************************************************************************
#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
//**************************************************************************
inline int CreateSem(int key)
{
int semid;
union semun arg;
/* create a semaphore set with 1 semaphore: */
if ((semid = semget((key_t) key, 1, 0660 | IPC_CREAT)) == -1) {
perror("semget");
exit(1);
}
/* initialize semaphore #0 to 1: */
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) == -1) {
perror("semctl");
exit(1);
}
return 0;
}
//**************************************************************************
inline int ShmSemLock(int key)
{
int semid;
struct sembuf sb = {0, -1, 0}; /* set to allocate resource */
/* grab the semaphore set created by seminit.c: */
if ((semid = semget(key, 1, 0)) == -1) {
perror("semget");
exit(1);
}
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(1);
}
return 0;
}
//**************************************************************************
inline int ShmSemUnlock(int key)
{
int semid;
struct sembuf sb = {0, 1, 0}; /* set to allocate resource */
/* grab the semaphore set created by seminit.c: */
if ((semid = semget(key, 1, 0)) == -1) {
perror("semget");
exit(1);
}
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(1);
}
return 0;
}
//**************************************************************************
inline void DeleteShm(int key)
{
int shmid;
unsigned char *shm;
if ((shmid = shmget((key_t) key, sizeof(int), IPC_CREAT | 0660)) < 0) {
perror("shmget");
exit(1);
}
shmctl(shmid, IPC_RMID, NULL); // Delete shared memory segment
}
//**************************************************************************
inline void PutIntoShm(int key, unsigned char *data, int size, int lockkey = 0)
{
int shmid;
unsigned char *shm;
int totsize = size+sizeof(int);
if (lockkey)
ShmSemLock(lockkey);
DeleteShm(key);
if ((shmid = shmget((key_t) key, totsize, IPC_CREAT | 0660)) < 0) {
perror("shmget");
exit(1);
}
if ((shm = (unsigned char *) shmat(shmid, NULL, 0)) == (unsigned char *) -1) {
perror("shmat");
exit(1);
}
memcpy(shm, &size, sizeof(int));
memcpy(shm+sizeof(int), data, size);
shmdt((char *) shm); // Detach shared memory segment
if (lockkey)
ShmSemUnlock(lockkey);
}
//**************************************************************************
inline void GetFromShm(int key, unsigned char **dataptr, int *size, int lockkey = 0)
{
int shmid;
unsigned char *shm;
if (lockkey)
ShmSemLock(lockkey);
if ((shmid = shmget((key_t) key, sizeof(int), IPC_CREAT | 0660)) < 0) {
perror("shmget");
exit(1);
}
if ((shm = (unsigned char *) shmat(shmid, NULL, SHM_RDONLY)) == (unsigned char *) -1) {
perror("shmat");
exit(1);
}
memcpy(size, shm, sizeof(int));
shmdt((char *) shm); // Detach shared memory segment
if ((shmid = shmget((key_t) key, *size+sizeof(int), IPC_CREAT | 0660)) < 0) {
perror("shmget");
exit(1);
}
if ((shm = (unsigned char *) shmat(shmid, NULL, 0)) == (unsigned char *) -1) {
perror("shmat");
exit(1);
}
unsigned char *data = NULL;
ALLOC1D(&data, *size);
*dataptr = data;
memcpy(data, shm+sizeof(int), *size);
shmdt((char *) shm); // Detach shared memory segment
if (lockkey)
ShmSemUnlock(lockkey);
}
//**************************************************************************
inline void DeleteSem(int key)
{
int semid;
union semun arg;
/* grab the semaphore set created by seminit.c: */
if ((semid = semget((key_t) key, 1, 0)) == -1) {
perror("semget");
exit(1);
}
/* remove it: */
if (semctl(semid, 0, IPC_RMID, arg) == -1) {
perror("semctl");
exit(1);
}
}
//**************************************************************************