/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "tlog.h" #include "shmem.h" #define KEY 101 #define PATH "/bin" void * attachSharedMemory(int key, char *path, int size, int rdonly) { key_t shm_key; int shm_id, flags=0; void *shm; if ( size>0 && rdonly ) return NULL; shm_key = ftok( (path) ? path : PATH, (key) ? key : KEY); /* Get IPC key */ if ((int) shm_key == -1) tlog(TL_CRIT|TL_EXIT, "Ftok error: %s", strerror(errno)); if (size > 0) flags = IPC_CREAT | IPC_EXCL | 0644; shm_id = shmget(shm_key, size, flags); /* Get SHM segment */ if (shm_id == -1) { if ( errno == EEXIST || errno == ENOENT ) return NULL; else tlog(TL_CRIT|TL_EXIT, "shmget error: %s", strerror(errno)); } flags = ( rdonly ) ? SHM_RDONLY : 0; shm = shmat(shm_id, 0, flags); /* Attach SHM segment */ if ( shm == (void*)-1 ) tlog(TL_CRIT|TL_EXIT, "shmat error: %s", strerror(errno)); return shm; } void detachSharedMemory(void *shm) { if ( shmdt(shm) == -1 ) tlog(TL_CRIT, "shmdt error: %s", strerror(errno)); } int attachSemaphore(int key, char *path) { key_t shm_key; int sem_id; shm_key = ftok( (path) ? path : PATH, (key) ? key : KEY); /* Get IPC key */ if ((int) shm_key == -1) tlog(TL_CRIT|TL_EXIT, "Ftok error: %s", strerror(errno)); sem_id = semget(shm_key, 1, 0); if ( sem_id == -1 ) { if ( errno == ENOENT ) { /* not exists */ sem_id = semget(shm_key, 1, IPC_CREAT | IPC_EXCL | 0644); if ( sem_id == -1 ) tlog(TL_CRIT|TL_EXIT, "semget error: %s", strerror(errno)); if ( semctl( sem_id, 0, SETVAL, 1 ) == -1 ) tlog(TL_CRIT|TL_EXIT, "sysctl error: %s", strerror(errno)); } else tlog(TL_CRIT|TL_EXIT, "semget error: %s", strerror(errno)); } return sem_id; } void releaseSemaphore(int sem_id) { struct sembuf sem; sem.sem_num = 0; sem.sem_flg = 0; sem.sem_op = 1; if (semop(sem_id, &sem, 1) == -1) tlog(TL_CRIT|TL_EXIT, "semop error: %s", strerror(errno)); } void lockSemaphore(int sem_id) { struct sembuf sem; sem.sem_num = 0; sem.sem_flg = 0; sem.sem_op = -1; if (semop(sem_id, &sem, 1) == -1) tlog(TL_CRIT|TL_EXIT, "semop error: %s", strerror(errno)); }