--- libaitsess/src/aitsess.c 2011/04/30 21:35:21 1.2 +++ libaitsess/src/aitsess.c 2011/09/07 13:11:56 1.3 @@ -3,17 +3,54 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitsess.c,v 1.2 2011/04/30 21:35:21 misho Exp $ +* $Id: aitsess.c,v 1.3 2011/09/07 13:11:56 misho Exp $ * -*************************************************************************/ +************************************************************************** +The ELWIX and AITNET software is distributed under the following +terms: + +All of the documentation and software included in the ELWIX and AITNET +Releases is copyrighted by ELWIX - Sofia/Bulgaria + +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + by Michael Pounov . 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. All advertising materials mentioning features or use of this software + must display the following acknowledgement: +This product includes software developed by Michael Pounov +ELWIX - Embedded LightWeight unIX and its contributors. +4. Neither the name of AITNET nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY AITNET AND 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 THE REGENTS OR 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 "global.h" #include "aitsess.h" #pragma GCC visibility push(hidden) -int sessErrno; -char sessError[MAX_STR + 1]; +int sess_Errno; +char sess_Error[STRSIZ]; #pragma GCC visibility pop @@ -22,41 +59,45 @@ char sessError[MAX_STR + 1]; // Error maintenance functions ... // sess_GetErrno() Get error code of last operation -inline int sess_GetErrno() +inline int +sess_GetErrno() { - return sessErrno; + return sess_Errno; } // sess_GetError() Get error text of last operation -inline const char *sess_GetError() +inline const char * +sess_GetError() { - return sessError; + return sess_Error; } -// sessDbg() Debug/Logging operations -static inline int sessDbg(FILE *f, char *fmt, ...) +// sess_SetErr() Set error to variables for internal use!!! +inline void +sess_SetErr(int eno, char *estr, ...) { - int ret = 0; va_list lst; - va_start(lst, fmt); - ret = vfprintf(f, fmt, lst); + sess_Errno = eno; + memset(sess_Error, 0, sizeof sess_Error); + va_start(lst, estr); + vsnprintf(sess_Error, sizeof sess_Error, estr, lst); va_end(lst); - - return ret; } // ----------------------------------------------------------- /* * initSession() Initializing session structure, if session file not exists creating with specified tech - * @cnID = Technology using in session. SHARED_IPC IPC tech; SHARED_MAP BSD MemoryMap tech + * @pnID = Technology using in session. + SHARED_IPC IPC tech; SHARED_MAP BSD MemoryMap tech or if =NULL SHARED_IPC * @csFName = Session filename for build key and identified - * @Sess = Session item + * @Sess = Session item, if =NULL allocate memory for session after use must be free! * return: 0 OK new key created, -1 error: no memory or file not created, 1 OK key finded */ -inline int initSession(const int cnID, const char *csFName, tagSess ** __restrict Sess) +inline int +initSession(int *pnID, const char *csFName, tagSess ** __restrict Sess) { - int h, ret = 0; - char szStr[MAX_STR + 1]; + int h, ret = 0, id = SHARED_IPC; + char szStr[STRSIZ]; if (!*Sess) { *Sess = malloc(sizeof(tagSess)); @@ -64,43 +105,68 @@ inline int initSession(const int cnID, const char *csF LOGERR; return -1; } - } - memset(*Sess, 0, sizeof(tagSess)); + } else + memset(*Sess, 0, sizeof(tagSess)); + if (pnID && *pnID) + id = *pnID; - // If key file exist, session already connected - if (!access(csFName, F_OK)) - ret = 1; - // Build new key & new session - h = open(csFName, O_WRONLY | O_CREAT, MEM_MODE); + h = open(csFName, O_WRONLY | O_CREAT | O_EXCL, MEM_MODE); if (h == -1) { - LOGERR; - free(*Sess); - return -1; - } - - bzero(szStr, MAX_STR + 1); - switch (cnID) { - case SHARED_IPC: - strcpy(szStr, "IPC@"); - break; - case SHARED_MAP: - strcpy(szStr, "MAP@"); - break; - default: - errno = EPROTONOSUPPORT; + if (errno != EEXIST) { LOGERR; - + free(*Sess); + return -1; + } + /* If key file exist, session already connected */ + h = open(csFName, O_RDONLY); + if (h == -1) { + LOGERR; + free(*Sess); + return -1; + } + ret = read(h, szStr, sizeof szStr); + if (ret == -1) { + LOGERR; close(h); - unlink(csFName); free(*Sess); return -1; + } + if (!strncmp(szStr, "IPC@", 4)) + id = SHARED_IPC; + else if (!strncmp(szStr, "MAP@", 4)) + id = SHARED_MAP; + else { + sess_SetErr(EPROTONOSUPPORT, "Error:: Session type not supported"); + close(h); + free(*Sess); + return -1; + } + + ret = 1; /* key found */ + } else { + /* Build new key & new session */ + switch (id) { + case SHARED_IPC: + strlcpy(szStr, "IPC@", sizeof szStr); + break; + case SHARED_MAP: + strlcpy(szStr, "MAP@", sizeof szStr); + break; + default: + sess_SetErr(EPROTONOSUPPORT, "Error:: Session type not supported"); + close(h); + unlink(csFName); + free(*Sess); + return -1; + } + strlcat(szStr, "ELWIX_Session ("PACKAGE_STRING")\n", sizeof szStr); + write(h, szStr, strlen(szStr)); + + ret = 0; /* new key created */ } - strcat(szStr, "AN_Session ver"); - strcat(szStr, "\n"); - write(h, szStr, strlen(szStr)); close(h); - (*Sess)->type = cnID; + (*Sess)->type = id; return ret; } @@ -109,9 +175,14 @@ inline int initSession(const int cnID, const char *csF * @csFName = Session filename for delete, if NULL nothing delete * @Sess = Session item */ -inline void freeSession(const char *csFName, tagSess ** __restrict Sess) +inline void +freeSession(const char *csFName, tagSess ** __restrict Sess) { - (*Sess)->type ^= (*Sess)->type; + assert(Sess); + if (!Sess) + return; + + (*Sess)->type = SHARED_UNKNOWN; if (csFName) unlink(csFName); if (*Sess) @@ -128,17 +199,17 @@ inline void freeSession(const char *csFName, tagSess * * @Sess = Session item * return: 0 Ok successful, -1 error: not allocated resources */ -int map_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess) +int +map_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess) { - int ret = 0; - char szSName[2][FILENAME_MAX + 1]; - void *mem; + int ret = 0, id = SHARED_MAP; + char szSName[2][FILENAME_MAX]; - ret = initSession(SHARED_MAP, csFName, Sess); + ret = initSession(&id, csFName, Sess); if (ret == -1 || !*Sess) return -1; - // genkey + /* genkey */ (*Sess)->key = ftok(csFName, cnSeed); if ((*Sess)->key == -1) { LOGERR; @@ -146,55 +217,39 @@ int map_createSession(const char *csFName, const int c return -1; } - // build semaphore & shared memory name - memset(szSName, 0, (FILENAME_MAX + 1) * 2); - snprintf(szSName[0], MAX_SEMNAME + 1, "/%X.ANS", (u_int) (*Sess)->key); - snprintf(szSName[1], FILENAME_MAX + 1, "%s-%x.ANM", csFName, (u_int) (*Sess)->key); + /* build semaphore & shared memory name */ + memset(szSName, 0, sizeof szSName); + snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) (*Sess)->key); + snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", csFName, (u_int) (*Sess)->key); - mem = malloc(cnSize); - if (!mem) { - LOGERR; - freeSession(csFName, Sess); - return -1; - } else - memset(mem, 0, cnSize); - - // create semaphore & add 1 + /* create semaphore & add 1 */ (*Sess)->id.sid = sem_open(szSName[0], O_CREAT, MEM_MODE); if ((*Sess)->id.sid == SEM_FAILED) { LOGERR; map_destroySession(csFName, Sess); - free(mem); return -1; } else sem_post((*Sess)->id.sid); - // create file for shared memory storage + /* create file for shared memory storage */ (*Sess)->mem.fd = open(szSName[1], O_RDWR | O_CREAT, MEM_MODE); if ((*Sess)->mem.fd == -1) { LOGERR; map_destroySession(csFName, Sess); - free(mem); return -1; } - // if is new shared memory session, fill file with zeros + /* if is new shared memory session, fill file with zeros */ if (!ret) { - if (write((*Sess)->mem.fd, mem, cnSize) != cnSize) { + if (lseek((*Sess)->mem.fd, cnSize - 1, SEEK_SET) == -1) { LOGERR; map_destroySession(csFName, Sess); - free(mem); return -1; - } - if (lseek((*Sess)->mem.fd, 0, SEEK_SET)) { - LOGERR; - map_destroySession(csFName, Sess); - free(mem); - return -1; - } + } else + write((*Sess)->mem.fd, "", 1); + lseek((*Sess)->mem.fd, 0, SEEK_SET); } (*Sess)->eom = cnSize; - free(mem); return ret; } @@ -203,29 +258,29 @@ int map_createSession(const char *csFName, const int c * @csFName = Session name for delete * @Sess = Session item */ -void map_destroySession(const char *csFName, tagSess ** __restrict Sess) +void +map_destroySession(const char *csFName, tagSess ** __restrict Sess) { int flg = 1; - char szSName[2][FILENAME_MAX + 1]; + char szSName[2][FILENAME_MAX]; - if (!*Sess) + assert(Sess); + if (!Sess || !*Sess) return; - bzero(szSName, (FILENAME_MAX + 1) * 2); - snprintf(szSName[0], MAX_SEMNAME + 1, "/%X.ANS", (u_int) (*Sess)->key); - snprintf(szSName[1], FILENAME_MAX + 1, "%s-%x.ANM", csFName, (u_int) (*Sess)->key); + memset(szSName, 0, sizeof szSName); + snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) (*Sess)->key); + snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", csFName, (u_int) (*Sess)->key); if ((*Sess)->id.sid != SEM_FAILED) { if (sem_close((*Sess)->id.sid) == -1) flg = 0; - if (sem_unlink(szSName[0]) == -1) /*flg = 0*/; } if ((*Sess)->mem.fd != -1) { if (close((*Sess)->mem.fd) == -1) flg = 0; - if (unlink(szSName[1]) == -1) /*flg = 0*/; } @@ -242,16 +297,17 @@ void map_destroySession(const char *csFName, tagSess * * @Sess = Session item * return: 0 Ok successful, -1 error: not allocated resources */ -int ipc_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess) +int +ipc_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess) { - int ret = 0; + int ret = 0, id = SHARED_IPC; union semun sems; - ret = initSession(SHARED_IPC, csFName, Sess); + ret = initSession(&id, csFName, Sess); if (ret == -1 || !*Sess) return -1; - // genkey + /* genkey */ (*Sess)->key = ftok(csFName, cnSeed); if ((*Sess)->key == -1) { LOGERR; @@ -259,14 +315,14 @@ int ipc_createSession(const char *csFName, const int c return -1; } - // create semaphore + /* create semaphore */ (*Sess)->id.semid = semget((*Sess)->key, 1, MEM_MODE | IPC_CREAT); if ((*Sess)->id.semid == -1) { LOGERR; ipc_destroySession(csFName, Sess); return -1; } - // if is new shared memory session, init sempahore with 1 + /* if is new shared memory session, init sempahore with 1 */ if (!ret) { sems.val = 1; if (semctl((*Sess)->id.semid, 0, SETVAL, sems) == -1) { @@ -276,7 +332,7 @@ int ipc_createSession(const char *csFName, const int c } } - // create shared memory object + /* create shared memory object */ (*Sess)->mem.shmid = shmget((*Sess)->key, cnSize, MEM_MODE | IPC_CREAT); if ((*Sess)->mem.shmid == -1) { LOGERR; @@ -293,13 +349,15 @@ int ipc_createSession(const char *csFName, const int c * @csFName = Session name for delete * @Sess = Session item */ -void ipc_destroySession(const char *csFName, tagSess ** __restrict Sess) +void +ipc_destroySession(const char *csFName, tagSess ** __restrict Sess) { int flg = 1; union semun sems; struct shmid_ds ds; - if (!*Sess) + assert(Sess); + if (!Sess || !*Sess) return; if ((*Sess)->id.semid != -1) @@ -320,14 +378,15 @@ void ipc_destroySession(const char *csFName, tagSess * * @procMem = Custom start address (optionl) *default must be 0* * return: NULL failed attach, !=NULL begin address of memory */ -inline void *map_attachSession(tagSess * __restrict s, void *procMem) +inline void * +map_attachSession(tagSess * __restrict s, void *procMem) { struct stat sb; if (!s) return NULL; - // Learn size of shared memory block + /* Learn size of shared memory block */ sync(); if (fstat(s->mem.fd, &sb) == -1) { LOGERR; @@ -335,7 +394,7 @@ inline void *map_attachSession(tagSess * __restrict s, } else s->eom = sb.st_size; - // attach to memory + /* attach to memory */ s->addr = mmap(procMem, s->eom, PROT_READ | PROT_WRITE, MAP_SHARED, s->mem.fd, 0); if (s->addr == MAP_FAILED) { LOGERR; @@ -349,7 +408,8 @@ inline void *map_attachSession(tagSess * __restrict s, * map_detachSession() MMAP Detach from shared memory * @s = Session item */ -inline void map_detachSession(tagSess * __restrict s) +inline void +map_detachSession(tagSess * __restrict s) { if (!s) return; @@ -368,7 +428,8 @@ inline void map_detachSession(tagSess * __restrict s) * @procMem = Custom start address (optionl) *default must be 0* * return: NULL failed attach, !=NULL begin address of memory */ -inline void *ipc_attachSession(tagSess * __restrict s, void *procMem) +inline void * +ipc_attachSession(tagSess * __restrict s, void *procMem) { if (!s) return NULL; @@ -386,7 +447,8 @@ inline void *ipc_attachSession(tagSess * __restrict s, * ipc_detachSession() IPC Detach from shared memory * @s = Session item */ -inline void ipc_detachSession(tagSess * __restrict s) +inline void +ipc_detachSession(tagSess * __restrict s) { if (!s) return; @@ -402,7 +464,8 @@ inline void ipc_detachSession(tagSess * __restrict s) * @s = Session item * return: -1 null session item, 0 not attached, 1 attached memory */ -inline int isAttached(tagSess * __restrict s) +inline int +isAttached(tagSess * __restrict s) { if (!s) return -1; @@ -415,7 +478,8 @@ inline int isAttached(tagSess * __restrict s) * map_notSemaphore() MMAP negative block if semaphore isn`t signaled * @s = Session item */ -inline void map_notSemaphore(tagSess * __restrict s) +inline void +map_notSemaphore(tagSess * __restrict s) { int i = -1; @@ -432,7 +496,8 @@ inline void map_notSemaphore(tagSess * __restrict s) * @s = Session item * return: -1 error: can`t return semaphore, 0 = false, 1 = true */ -inline int map_isSemaphored(tagSess * __restrict s) +inline int +map_isSemaphored(tagSess * __restrict s) { int val = -1; @@ -448,7 +513,8 @@ inline int map_isSemaphored(tagSess * __restrict s) * @s = Session item * return: 0 Ok, -1 error: can`t increment */ -inline int map_addSemaphore(tagSess * __restrict s) +inline int +map_addSemaphore(tagSess * __restrict s) { if (!s) return -1; @@ -461,7 +527,8 @@ inline int map_addSemaphore(tagSess * __restrict s) * @s = Session item * return: 0 Ok, -1 error: can`t decrement */ -inline int map_decSemaphore(tagSess * __restrict s) +inline int +map_decSemaphore(tagSess * __restrict s) { if (!s) return -1; @@ -473,7 +540,8 @@ inline int map_decSemaphore(tagSess * __restrict s) * ipc_notSemaphore() IPC negative block if semaphore isn`t signaled * @s = Session item */ -inline void ipc_notSemaphore(tagSess * __restrict s) +inline void +ipc_notSemaphore(tagSess * __restrict s) { struct sembuf sb = { 0, 0, 0 }; @@ -486,7 +554,8 @@ inline void ipc_notSemaphore(tagSess * __restrict s) * @s = Session item * return: -1 error: can`t return semaphore, 0 = false, 1 = true */ -inline int ipc_isSemaphored(tagSess * __restrict s) +inline int +ipc_isSemaphored(tagSess * __restrict s) { struct sembuf sb = { 0, 0, IPC_NOWAIT }; @@ -501,7 +570,8 @@ inline int ipc_isSemaphored(tagSess * __restrict s) * @s = Session item * return: 0 Ok, -1 error: can`t increment */ -inline int ipc_addSemaphore(tagSess * __restrict s) +inline int +ipc_addSemaphore(tagSess * __restrict s) { struct sembuf sb = { 0, 1, 0 }; @@ -516,7 +586,8 @@ inline int ipc_addSemaphore(tagSess * __restrict s) * @s = Session item * return: 0 Ok, -1 error: can`t decrement */ -inline int ipc_decSemaphore(tagSess * __restrict s) +inline int +ipc_decSemaphore(tagSess * __restrict s) { struct sembuf sb = { 0, -1, 0 };