Annotation of libaitsess/src/aitsess.c, revision 1.4

1.2       misho       1: /*************************************************************************
                      2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.4     ! misho       6: * $Id: aitsess.c,v 1.3.2.8 2012/02/10 23:15:27 misho Exp $
1.2       misho       7: *
1.3       misho       8: **************************************************************************
                      9: The ELWIX and AITNET software is distributed under the following
                     10: terms:
                     11: 
                     12: All of the documentation and software included in the ELWIX and AITNET
                     13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
                     14: 
                     15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
                     16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
                     17: 
                     18: Redistribution and use in source and binary forms, with or without
                     19: modification, are permitted provided that the following conditions
                     20: are met:
                     21: 1. Redistributions of source code must retain the above copyright
                     22:    notice, this list of conditions and the following disclaimer.
                     23: 2. Redistributions in binary form must reproduce the above copyright
                     24:    notice, this list of conditions and the following disclaimer in the
                     25:    documentation and/or other materials provided with the distribution.
                     26: 3. All advertising materials mentioning features or use of this software
                     27:    must display the following acknowledgement:
                     28: This product includes software developed by Michael Pounov <misho@elwix.org>
                     29: ELWIX - Embedded LightWeight unIX and its contributors.
                     30: 4. Neither the name of AITNET nor the names of its contributors
                     31:    may be used to endorse or promote products derived from this software
                     32:    without specific prior written permission.
                     33: 
                     34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
                     35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     44: SUCH DAMAGE.
                     45: */
1.1       misho      46: #include "global.h"
                     47: #include "aitsess.h"
                     48: 
                     49: 
                     50: #pragma GCC visibility push(hidden)
                     51: 
1.3       misho      52: int sess_Errno;
                     53: char sess_Error[STRSIZ];
1.1       misho      54: 
                     55: #pragma GCC visibility pop
                     56: 
                     57: // -----------------------------------------------------------
                     58: 
                     59: // Error maintenance functions ...
                     60: 
                     61: // sess_GetErrno() Get error code of last operation
1.3       misho      62: inline int
                     63: sess_GetErrno()
1.1       misho      64: {
1.3       misho      65:        return sess_Errno;
1.1       misho      66: }
                     67: // sess_GetError() Get error text of last operation
1.3       misho      68: inline const char *
                     69: sess_GetError()
1.1       misho      70: {
1.3       misho      71:        return sess_Error;
1.1       misho      72: }
1.3       misho      73: // sess_SetErr() Set error to variables for internal use!!!
                     74: inline void
                     75: sess_SetErr(int eno, char *estr, ...)
1.1       misho      76: {
                     77:        va_list lst;
                     78: 
1.3       misho      79:        sess_Errno = eno;
                     80:        memset(sess_Error, 0, sizeof sess_Error);
                     81:        va_start(lst, estr);
                     82:        vsnprintf(sess_Error, sizeof sess_Error, estr, lst);
1.1       misho      83:        va_end(lst);
                     84: }
                     85: 
                     86: // -----------------------------------------------------------
                     87: 
                     88: /*
1.4     ! misho      89:  * sess_initSession() Initializing session structure, if session file not exists creating with specified tech
        !            90:  *
        !            91:  * @id = Technology using in session. SHARED_IPC IPC tech orSHARED_MAP BSD MemoryMap tech
1.1       misho      92:  * @csFName = Session filename for build key and identified
1.3       misho      93:  * @Sess = Session item, if =NULL allocate memory for session after use must be free!
1.1       misho      94:  * return: 0 OK new key created, -1 error: no memory or file not created, 1 OK key finded
                     95: */
1.4     ! misho      96: int
        !            97: sess_initSession(int id, const char *csFName, ait_sess_t ** __restrict Sess)
1.1       misho      98: {
1.4     ! misho      99:        int h, ret = 0;
1.3       misho     100:        char szStr[STRSIZ];
1.1       misho     101: 
1.4     ! misho     102:        if (!csFName) {
        !           103:                sess_SetErr(EINVAL, "Filename is NULL");
        !           104:                return -1;
        !           105:        }
        !           106:        if (id < SHARED_UNKNOWN || id > SHARED_MAP) {
        !           107:                sess_SetErr(EPROTONOSUPPORT, "Session type not supported");
        !           108:                return -1;
        !           109:        }
        !           110: 
1.1       misho     111:        if (!*Sess) {
1.4     ! misho     112:                *Sess = malloc(sizeof(ait_sess_t));
1.1       misho     113:                if (!*Sess) {
                    114:                        LOGERR;
                    115:                        return -1;
                    116:                }
1.4     ! misho     117:        }
        !           118:        memset(*Sess, 0, sizeof(ait_sess_t));
        !           119:        strlcpy((*Sess)->name, csFName, sizeof (*Sess)->name);
1.1       misho     120: 
1.4     ! misho     121:        h = open((*Sess)->name, O_WRONLY | O_CREAT | O_EXCL, MEM_MODE);
1.1       misho     122:        if (h == -1) {
1.3       misho     123:                if (errno != EEXIST) {
                    124:                        LOGERR;
                    125:                        free(*Sess);
                    126:                        return -1;
                    127:                }
                    128:                /* If key file exist, session already connected */
1.4     ! misho     129:                h = open((*Sess)->name, O_RDONLY);
1.3       misho     130:                if (h == -1) {
                    131:                        LOGERR;
                    132:                        free(*Sess);
                    133:                        return -1;
                    134:                }
                    135:                ret = read(h, szStr, sizeof szStr);
                    136:                if (ret == -1) {
1.1       misho     137:                        LOGERR;
                    138:                        close(h);
                    139:                        free(*Sess);
                    140:                        return -1;
1.3       misho     141:                }
1.4     ! misho     142:                if (!strncmp(szStr, "IPC@", 4) && id == SHARED_IPC) {
        !           143:                        ret = 1;
        !           144: 
        !           145:                        (*Sess)->sess.create = (int (*)(int, long, void*, ...)) ipc_createSession;
        !           146:                        (*Sess)->sess.destroy = (void (*)(void*)) ipc_destroySession;
        !           147:                        (*Sess)->sess.attach = (void* (*)(void*, void*)) ipc_attachSession;
        !           148:                        (*Sess)->sess.detach = (void (*)(void*)) ipc_detachSession;
        !           149:                        (*Sess)->sess.notSem = (void (*)(void*)) ipc_notSemaphore;
        !           150:                        (*Sess)->sess.isSemOK = (int (*)(void*)) ipc_isSemaphoreOK;
        !           151:                        (*Sess)->sess.incSem = (int (*)(void*)) ipc_incSemaphore;
        !           152:                        (*Sess)->sess.decSem = (int (*)(void*)) ipc_decSemaphore;
        !           153:                } else if (!strncmp(szStr, "MAP@", 4) && id == SHARED_MAP) {
        !           154:                        ret = 1;
        !           155: 
        !           156:                        (*Sess)->sess.create = (int (*)(int, long, void*, ...)) map_createSession;
        !           157:                        (*Sess)->sess.destroy = (void (*)(void*)) map_destroySession;
        !           158:                        (*Sess)->sess.attach = (void* (*)(void*, void*)) map_attachSession;
        !           159:                        (*Sess)->sess.detach = (void (*)(void*)) map_detachSession;
        !           160:                        (*Sess)->sess.notSem = (void (*)(void*)) map_notSemaphore;
        !           161:                        (*Sess)->sess.isSemOK = (int (*)(void*)) map_isSemaphoreOK;
        !           162:                        (*Sess)->sess.incSem = (int (*)(void*)) map_incSemaphore;
        !           163:                        (*Sess)->sess.decSem = (int (*)(void*)) map_decSemaphore;
        !           164:                } else {
        !           165:                        sess_SetErr(EPROTONOSUPPORT, 
        !           166:                                        "Session type not supported or wrong session type");
1.3       misho     167:                        close(h);
                    168:                        free(*Sess);
                    169:                        return -1;
                    170:                }
1.4     ! misho     171:                /* key found */
1.3       misho     172:        } else {
                    173:                /* Build new key & new session */
1.4     ! misho     174:                if (id == SHARED_IPC) {
        !           175:                        strlcpy(szStr, "IPC@", sizeof szStr);
        !           176: 
        !           177:                        (*Sess)->sess.create = (int (*)(int, long, void*, ...)) ipc_createSession;
        !           178:                        (*Sess)->sess.destroy = (void (*)(void*)) ipc_destroySession;
        !           179:                        (*Sess)->sess.attach = (void* (*)(void*, void*)) ipc_attachSession;
        !           180:                        (*Sess)->sess.detach = (void (*)(void*)) ipc_detachSession;
        !           181:                        (*Sess)->sess.notSem = (void (*)(void*)) ipc_notSemaphore;
        !           182:                        (*Sess)->sess.isSemOK = (int (*)(void*)) ipc_isSemaphoreOK;
        !           183:                        (*Sess)->sess.incSem = (int (*)(void*)) ipc_incSemaphore;
        !           184:                        (*Sess)->sess.decSem = (int (*)(void*)) ipc_decSemaphore;
        !           185:                } else if (id == SHARED_MAP) {
        !           186:                        strlcpy(szStr, "MAP@", sizeof szStr);
        !           187: 
        !           188:                        (*Sess)->sess.create = (int (*)(int, long, void*, ...)) map_createSession;
        !           189:                        (*Sess)->sess.destroy = (void (*)(void*)) map_destroySession;
        !           190:                        (*Sess)->sess.attach = (void* (*)(void*, void*)) map_attachSession;
        !           191:                        (*Sess)->sess.detach = (void (*)(void*)) map_detachSession;
        !           192:                        (*Sess)->sess.notSem = (void (*)(void*)) map_notSemaphore;
        !           193:                        (*Sess)->sess.isSemOK = (int (*)(void*)) map_isSemaphoreOK;
        !           194:                        (*Sess)->sess.incSem = (int (*)(void*)) map_incSemaphore;
        !           195:                        (*Sess)->sess.decSem = (int (*)(void*)) map_decSemaphore;
        !           196:                } else {
        !           197:                        sess_SetErr(EINVAL, "Session type must be specified");
        !           198:                        close(h);
        !           199:                        unlink(csFName);
        !           200:                        free(*Sess);
        !           201:                        return -1;
1.3       misho     202:                }
                    203:                strlcat(szStr, "ELWIX_Session ("PACKAGE_STRING")\n", sizeof szStr);
                    204:                write(h, szStr, strlen(szStr));
                    205: 
1.4     ! misho     206:                ret = 0;
        !           207:                /* new key created */
1.1       misho     208:        }
                    209:        close(h);
                    210: 
1.3       misho     211:        (*Sess)->type = id;
1.4     ! misho     212:        (*Sess)->zcpy = (char) ret;
1.1       misho     213:        return ret;
                    214: }
                    215: 
                    216: /*
1.4     ! misho     217:  * sess_freeSession() Free allocated memory for session item and delete session file if present name
        !           218:  *
1.1       misho     219:  * @Sess = Session item
1.4     ! misho     220:  * return: none
1.1       misho     221: */
1.4     ! misho     222: void
        !           223: sess_freeSession(ait_sess_t ** __restrict Sess)
1.1       misho     224: {
1.4     ! misho     225:        if (!Sess || !(*Sess))
1.3       misho     226:                return;
                    227: 
1.4     ! misho     228:        if ((*Sess)->addr)
        !           229:                DETACH_MEMORY(*Sess);
        !           230: 
        !           231:        /*
        !           232:        memset(&(*Sess)->sess, 0, sizeof (*Sess)->sess);
        !           233: 
1.3       misho     234:        (*Sess)->type = SHARED_UNKNOWN;
1.4     ! misho     235:        */
        !           236: 
        !           237:        free(*Sess);
1.1       misho     238:        *Sess = NULL;
                    239: }
                    240: 
                    241: 
                    242: /*
                    243:  * map_createSession() MMAP Created session and allocated resources
1.4     ! misho     244:  *
        !           245:  * @nSeed = Seed for securing key, if =-1 must add ready for use key
        !           246:  * @nSize = Allocated shared memory size in bytes
1.1       misho     247:  * @Sess = Session item
1.4     ! misho     248:  * @... = If nSeed == -1 add ready for use key value
1.1       misho     249:  * return: 0 Ok successful, -1 error: not allocated resources
                    250: */
1.3       misho     251: int
1.4     ! misho     252: map_createSession(int nSeed, long nSize, ait_sess_t * __restrict Sess, ...)
1.1       misho     253: {
1.3       misho     254:        char szSName[2][FILENAME_MAX];
1.4     ! misho     255:        va_list lst;
1.1       misho     256: 
1.4     ! misho     257:        if (!Sess || !*Sess->name)
1.1       misho     258:                return -1;
                    259: 
1.4     ! misho     260:        if (nSeed != -1) {
        !           261:                /* genkey */
        !           262:                Sess->key = ftok(Sess->name, nSeed);
        !           263:                if (Sess->key == -1) {
        !           264:                        LOGERR;
        !           265:                        return -1;
        !           266:                }
        !           267:        } else {
        !           268:                /* get key from va_args */
        !           269:                va_start(lst, Sess);
        !           270:                Sess->key = va_arg(lst, key_t);
        !           271:                va_end(lst);
1.1       misho     272:        }
                    273: 
1.3       misho     274:        /* build semaphore & shared memory name */
                    275:        memset(szSName, 0, sizeof szSName);
1.4     ! misho     276:        snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) Sess->key);
        !           277:        snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", Sess->name, (u_int) Sess->key);
1.1       misho     278: 
1.3       misho     279:        /* create semaphore & add 1 */
1.4     ! misho     280:        Sess->id.sid = sem_open(szSName[0], O_CREAT, MEM_MODE);
        !           281:        if (Sess->id.sid == SEM_FAILED) {
1.1       misho     282:                LOGERR;
1.4     ! misho     283:                map_destroySession(Sess);
1.1       misho     284:                return -1;
1.4     ! misho     285:        }
        !           286:        /* if is new shared memory session, init sempahore with 1 */
        !           287:        if (!Sess->zcpy)
        !           288:                sem_post(Sess->id.sid);
1.1       misho     289: 
1.3       misho     290:        /* create file for shared memory storage */
1.4     ! misho     291:        Sess->mem.fd = open(szSName[1], O_RDWR | O_CREAT, MEM_MODE);
        !           292:        if (Sess->mem.fd == -1) {
1.1       misho     293:                LOGERR;
1.4     ! misho     294:                map_destroySession(Sess);
1.1       misho     295:                return -1;
                    296:        }
1.3       misho     297:        /* if is new shared memory session, fill file with zeros */
1.4     ! misho     298:        if (!Sess->zcpy) {
        !           299:                if (lseek(Sess->mem.fd, nSize - 1, SEEK_SET) == -1) {
1.1       misho     300:                        LOGERR;
1.4     ! misho     301:                        map_destroySession(Sess);
1.1       misho     302:                        return -1;
1.3       misho     303:                } else
1.4     ! misho     304:                        write(Sess->mem.fd, "", 1);
        !           305:                lseek(Sess->mem.fd, 0, SEEK_SET);
1.1       misho     306:        }
1.4     ! misho     307:        Sess->eom = nSize;
1.1       misho     308: 
1.4     ! misho     309:        return (int) Sess->zcpy;
1.1       misho     310: }
                    311: 
                    312: /*
                    313:  * map_destroySession() MMAP free shared resources
1.4     ! misho     314:  *
1.1       misho     315:  * @Sess = Session item
1.4     ! misho     316:  * return: none
1.1       misho     317: */
1.3       misho     318: void
1.4     ! misho     319: map_destroySession(ait_sess_t * __restrict Sess)
1.1       misho     320: {
1.3       misho     321:        char szSName[2][FILENAME_MAX];
1.1       misho     322: 
1.4     ! misho     323:        if (!Sess || sess_isAttached(Sess) || !*Sess->name)
1.1       misho     324:                return;
                    325: 
1.3       misho     326:        memset(szSName, 0, sizeof szSName);
1.4     ! misho     327:        snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) Sess->key);
        !           328:        snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", Sess->name, (u_int) Sess->key);
1.1       misho     329: 
1.4     ! misho     330:        if (Sess->id.sid != SEM_FAILED) {
        !           331:                sem_close(Sess->id.sid);
        !           332:                sem_unlink(szSName[0]);
        !           333:        }
        !           334:        if (Sess->mem.fd > 2) {
        !           335:                close(Sess->mem.fd);
        !           336:                unlink(szSName[1]);
        !           337:        }
        !           338:        unlink(Sess->name);
        !           339:        memset(Sess->name, 0, sizeof Sess->name);
        !           340:        Sess->eom ^= Sess->eom;
        !           341:        Sess->key ^= Sess->key;
1.1       misho     342: }
                    343: 
                    344: /*
                    345:  * ipc_createSession() IPC Created session and allocated resources
1.4     ! misho     346:  *
        !           347:  * @nSeed = Seed for securing key, if =-1 must add ready for use key
        !           348:  * @nSize = Allocated shared memory size in bytes
1.1       misho     349:  * @Sess = Session item
1.4     ! misho     350:  * @... = If nSeed == -1 add ready for use key value
1.1       misho     351:  * return: 0 Ok successful, -1 error: not allocated resources
1.4     ! misho     352:  */
1.3       misho     353: int
1.4     ! misho     354: ipc_createSession(int nSeed, long nSize, ait_sess_t * __restrict Sess, ...)
1.1       misho     355: {
                    356:        union semun sems;
1.4     ! misho     357:        va_list lst;
1.1       misho     358: 
1.4     ! misho     359:        if (!Sess || !*Sess->name)
1.1       misho     360:                return -1;
                    361: 
1.4     ! misho     362:        if (nSeed != -1) {
        !           363:                /* genkey */
        !           364:                Sess->key = ftok(Sess->name, nSeed);
        !           365:                if (Sess->key == -1) {
        !           366:                        LOGERR;
        !           367:                        return -1;
        !           368:                }
        !           369:        } else {
        !           370:                /* get key from va_args */
        !           371:                va_start(lst, Sess);
        !           372:                Sess->key = va_arg(lst, key_t);
        !           373:                va_end(lst);
1.1       misho     374:        }
                    375: 
1.3       misho     376:        /* create semaphore */
1.4     ! misho     377:        Sess->id.semid = semget(Sess->key, 1, MEM_MODE | IPC_CREAT);
        !           378:        if (Sess->id.semid == -1) {
1.1       misho     379:                LOGERR;
1.4     ! misho     380:                ipc_destroySession(Sess);
1.1       misho     381:                return -1;
                    382:        }
1.3       misho     383:        /* if is new shared memory session, init sempahore with 1 */
1.4     ! misho     384:        if (!Sess->zcpy) {
1.1       misho     385:                sems.val = 1;
1.4     ! misho     386:                if (semctl(Sess->id.semid, 0, SETVAL, sems) == -1) {
1.1       misho     387:                        LOGERR;
1.4     ! misho     388:                        ipc_destroySession(Sess);
1.1       misho     389:                        return -1;
                    390:                }
                    391:        }
                    392: 
1.3       misho     393:        /* create shared memory object */
1.4     ! misho     394:        Sess->mem.shmid = shmget(Sess->key, nSize, MEM_MODE | IPC_CREAT);
        !           395:        if (Sess->mem.shmid == -1) {
1.1       misho     396:                LOGERR;
1.4     ! misho     397:                ipc_destroySession(Sess);
1.1       misho     398:                return -1;
1.4     ! misho     399:        } else
        !           400:                Sess->eom = nSize;
1.1       misho     401: 
1.4     ! misho     402:        return (int) Sess->zcpy;
1.1       misho     403: }
                    404: 
                    405: /*
                    406:  * ipc_destroySession() IPC free shared resources
1.4     ! misho     407:  *
1.1       misho     408:  * @Sess = Session item
1.4     ! misho     409:  * return: none
        !           410:  */
1.3       misho     411: void
1.4     ! misho     412: ipc_destroySession(ait_sess_t * __restrict Sess)
1.1       misho     413: {
                    414:        union semun sems;
                    415:        struct shmid_ds ds;
                    416: 
1.4     ! misho     417:        if (!Sess || sess_isAttached(Sess))
1.1       misho     418:                return;
                    419: 
1.4     ! misho     420:        if (Sess->id.semid != -1)
        !           421:                semctl(Sess->id.semid, 0, IPC_RMID, &sems);
        !           422:        if (Sess->mem.shmid != -1)
        !           423:                shmctl(Sess->mem.shmid, IPC_RMID, &ds);
        !           424:        unlink(Sess->name);
        !           425:        memset(Sess->name, 0, sizeof Sess->name);
        !           426:        Sess->eom ^= Sess->eom;
        !           427:        Sess->key ^= Sess->key;
1.1       misho     428: }
                    429: 
                    430: 
                    431: /*
                    432:  * map_attachSession() MMAP Attach to shared memory & return begin address
1.4     ! misho     433:  *
1.1       misho     434:  * @s = Session item
                    435:  * @procMem = Custom start address (optionl) *default must be 0*
                    436:  * return: NULL failed attach, !=NULL begin address of memory
1.4     ! misho     437:  */
        !           438: void *
        !           439: map_attachSession(ait_sess_t * __restrict s, void *procMem)
1.1       misho     440: {
                    441:        if (!s)
                    442:                return NULL;
                    443: 
                    444:        sync();
                    445: 
1.3       misho     446:        /* attach to memory */
1.1       misho     447:        s->addr = mmap(procMem, s->eom, PROT_READ | PROT_WRITE, MAP_SHARED, s->mem.fd, 0);
                    448:        if (s->addr == MAP_FAILED) {
                    449:                LOGERR;
                    450:                s->addr = NULL;
                    451:        }
                    452: 
                    453:        return s->addr;
                    454: }
                    455: 
                    456: /*
                    457:  * map_detachSession() MMAP Detach from shared memory
1.4     ! misho     458:  *
1.1       misho     459:  * @s = Session item
1.4     ! misho     460:  * return: none
        !           461:  */
        !           462: void
        !           463: map_detachSession(ait_sess_t * __restrict s)
1.1       misho     464: {
                    465:        if (!s)
                    466:                return;
                    467: 
                    468:        msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);
                    469: 
                    470:        if (s->addr && s->eom) {
                    471:                munmap(s->addr, s->eom);
                    472:                s->addr = NULL;
                    473:        }
                    474: }
                    475: 
                    476: /*
                    477:  * ipc_attachSession() IPC Attach to shared memory & return begin address
1.4     ! misho     478:  *
1.1       misho     479:  * @s = Session item
                    480:  * @procMem = Custom start address (optionl) *default must be 0*
                    481:  * return: NULL failed attach, !=NULL begin address of memory
1.4     ! misho     482:  */
        !           483: void *
        !           484: ipc_attachSession(ait_sess_t * __restrict s, void *procMem)
1.1       misho     485: {
                    486:        if (!s)
                    487:                return NULL;
                    488: 
                    489:        s->addr = shmat(s->mem.shmid, procMem, 0);
                    490:        if (s->addr == (void*) -1) {
                    491:                LOGERR;
                    492:                s->addr = NULL;
                    493:        }
                    494: 
                    495:        return s->addr;
                    496: }
                    497: 
                    498: /*
                    499:  * ipc_detachSession() IPC Detach from shared memory
1.4     ! misho     500:  *
1.1       misho     501:  * @s = Session item
1.4     ! misho     502:  * return: none
        !           503:  */
        !           504: void
        !           505: ipc_detachSession(ait_sess_t * __restrict s)
1.1       misho     506: {
                    507:        if (!s)
                    508:                return;
                    509: 
                    510:        if (s->addr) {
                    511:                shmdt(s->addr);
                    512:                s->addr = NULL;
                    513:        }
                    514: }
                    515: 
1.2       misho     516: /*
1.4     ! misho     517:  * sess_isAttached() Check for attached shared memory
        !           518:  *
1.2       misho     519:  * @s = Session item
                    520:  * return: -1 null session item, 0 not attached, 1 attached memory
1.4     ! misho     521:  */
1.3       misho     522: inline int
1.4     ! misho     523: sess_isAttached(ait_sess_t * __restrict s)
1.2       misho     524: {
                    525:        if (!s)
                    526:                return -1;
                    527: 
                    528:        return (s->addr ? 1 : 0);
                    529: }
                    530: 
1.1       misho     531: 
                    532: /*
                    533:  * map_notSemaphore() MMAP negative block if semaphore isn`t signaled
1.4     ! misho     534:  *
1.1       misho     535:  * @s = Session item
1.4     ! misho     536:  * return: none
        !           537:  */
        !           538: void
        !           539: map_notSemaphore(ait_sess_t * __restrict s)
1.1       misho     540: {
                    541:        int i = -1;
                    542: 
                    543:        if (!s)
                    544:                return;
                    545: 
                    546:        sem_getvalue(s->id.sid, &i);
1.4     ! misho     547:        while (i > 0) {
1.1       misho     548:                sem_wait(s->id.sid);
1.4     ! misho     549:                i--;
        !           550:        }
1.1       misho     551: }
                    552: 
                    553: /*
1.4     ! misho     554:  * map_isSemaphoreOK() MMAP Check semaphore
        !           555:  *
1.1       misho     556:  * @s = Session item
                    557:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
1.4     ! misho     558:  */
        !           559: int
        !           560: map_isSemaphoreOK(ait_sess_t * __restrict s)
1.1       misho     561: {
                    562:        int val = -1;
                    563: 
                    564:        if (!s)
                    565:                return -1;
                    566: 
                    567:        sem_getvalue(s->id.sid, &val);
1.4     ! misho     568:        return (val ? 0 : 1);
1.1       misho     569: }
                    570: 
                    571: /*
1.4     ! misho     572:  * map_incSemaphore() MMAP unblock semaphore, increment semaphore
        !           573:  *
1.1       misho     574:  * @s = Session item
                    575:  * return: 0 Ok, -1 error: can`t increment 
1.4     ! misho     576:  */
        !           577: int
        !           578: map_incSemaphore(ait_sess_t * __restrict s)
1.1       misho     579: {
                    580:        if (!s)
                    581:                return -1;
                    582: 
                    583:        return sem_post(s->id.sid);
                    584: }
                    585: 
                    586: /*
                    587:  * map_decSemaphore() MMAP block semaphore, decrement semaphore
1.4     ! misho     588:  *
1.1       misho     589:  * @s = Session item
                    590:  * return: 0 Ok, -1 error: can`t decrement 
1.4     ! misho     591:  */
        !           592: int
        !           593: map_decSemaphore(ait_sess_t * __restrict s)
1.1       misho     594: {
                    595:        if (!s)
                    596:                return -1;
                    597: 
                    598:        return sem_wait(s->id.sid);
                    599: }
                    600: 
                    601: /*
                    602:  * ipc_notSemaphore() IPC negative block if semaphore isn`t signaled
1.4     ! misho     603:  *
1.1       misho     604:  * @s = Session item
1.4     ! misho     605:  * return: none
        !           606:  */
        !           607: void
        !           608: ipc_notSemaphore(ait_sess_t * __restrict s)
1.1       misho     609: {
                    610:        struct sembuf sb = { 0, 0, 0 };
                    611: 
                    612:        if (s)
                    613:                semop(s->id.semid, &sb, 1);
                    614: }
                    615: 
                    616: /*
1.4     ! misho     617:  * ipc_isSemaphoreOK() IPC Check semaphore
        !           618:  *
1.1       misho     619:  * @s = Session item
                    620:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
1.4     ! misho     621:  */
        !           622: int
        !           623: ipc_isSemaphoreOK(ait_sess_t * __restrict s)
1.1       misho     624: {
                    625:        struct sembuf sb = { 0, 0, IPC_NOWAIT };
                    626: 
                    627:        if (!s)
                    628:                return -1;
                    629: 
                    630:        return semop(s->id.semid, &sb, 1) + 1;
                    631: }
                    632: 
                    633: /*
1.4     ! misho     634:  * ipc_incSemaphore() IPC unblock semaphore, increment semaphore
        !           635:  *
1.1       misho     636:  * @s = Session item
                    637:  * return: 0 Ok, -1 error: can`t increment 
1.4     ! misho     638:  */
        !           639: int
        !           640: ipc_incSemaphore(ait_sess_t * __restrict s)
1.1       misho     641: {
                    642:        struct sembuf sb = { 0, 1, 0 };
                    643: 
                    644:        if (!s)
                    645:                return -1;
                    646: 
                    647:        return semop(s->id.semid, &sb, 1);
                    648: }
                    649: 
                    650: /*
                    651:  * ipc_decSemaphore() IPC block semaphore, decrement semaphore
1.4     ! misho     652:  *
1.1       misho     653:  * @s = Session item
                    654:  * return: 0 Ok, -1 error: can`t decrement 
1.4     ! misho     655:  */
        !           656: int
        !           657: ipc_decSemaphore(ait_sess_t * __restrict s)
1.1       misho     658: {
                    659:        struct sembuf sb = { 0, -1, 0 };
                    660: 
                    661:        if (!s)
                    662:                return -1;
                    663: 
                    664:        return semop(s->id.semid, &sb, 1);
                    665: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>