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

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.3     ! misho       6: * $Id: aitsess.c,v 1.2.2.4 2011/08/21 14:13:41 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: /*
                     89:  * initSession() Initializing session structure, if session file not exists creating with specified tech
1.3     ! misho      90:  * @pnID = Technology using in session. 
        !            91:        SHARED_IPC IPC tech; SHARED_MAP BSD MemoryMap tech or if =NULL SHARED_IPC
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.3     ! misho      96: inline int
        !            97: initSession(int *pnID, const char *csFName, tagSess ** __restrict Sess)
1.1       misho      98: {
1.3     ! misho      99:        int h, ret = 0, id = SHARED_IPC;
        !           100:        char szStr[STRSIZ];
1.1       misho     101: 
                    102:        if (!*Sess) {
                    103:                *Sess = malloc(sizeof(tagSess));
                    104:                if (!*Sess) {
                    105:                        LOGERR;
                    106:                        return -1;
                    107:                }
1.3     ! misho     108:        } else
        !           109:                memset(*Sess, 0, sizeof(tagSess));
        !           110:        if (pnID && *pnID)
        !           111:                id = *pnID;
1.1       misho     112: 
1.3     ! misho     113:        h = open(csFName, O_WRONLY | O_CREAT | O_EXCL, MEM_MODE);
1.1       misho     114:        if (h == -1) {
1.3     ! misho     115:                if (errno != EEXIST) {
        !           116:                        LOGERR;
        !           117:                        free(*Sess);
        !           118:                        return -1;
        !           119:                }
        !           120:                /* If key file exist, session already connected */
        !           121:                h = open(csFName, O_RDONLY);
        !           122:                if (h == -1) {
        !           123:                        LOGERR;
        !           124:                        free(*Sess);
        !           125:                        return -1;
        !           126:                }
        !           127:                ret = read(h, szStr, sizeof szStr);
        !           128:                if (ret == -1) {
1.1       misho     129:                        LOGERR;
                    130:                        close(h);
                    131:                        free(*Sess);
                    132:                        return -1;
1.3     ! misho     133:                }
        !           134:                if (!strncmp(szStr, "IPC@", 4))
        !           135:                        id = SHARED_IPC;
        !           136:                else if (!strncmp(szStr, "MAP@", 4))
        !           137:                        id = SHARED_MAP;
        !           138:                else {
        !           139:                        sess_SetErr(EPROTONOSUPPORT, "Error:: Session type not supported");
        !           140:                        close(h);
        !           141:                        free(*Sess);
        !           142:                        return -1;
        !           143:                }
        !           144: 
        !           145:                ret = 1;        /* key found */
        !           146:        } else {
        !           147:                /* Build new key & new session */
        !           148:                switch (id) {
        !           149:                        case SHARED_IPC:
        !           150:                                strlcpy(szStr, "IPC@", sizeof szStr);
        !           151:                                break;
        !           152:                        case SHARED_MAP:
        !           153:                                strlcpy(szStr, "MAP@", sizeof szStr);
        !           154:                                break;
        !           155:                        default:
        !           156:                                sess_SetErr(EPROTONOSUPPORT, "Error:: Session type not supported");
        !           157:                                close(h);
        !           158:                                unlink(csFName);
        !           159:                                free(*Sess);
        !           160:                                return -1;
        !           161:                }
        !           162:                strlcat(szStr, "ELWIX_Session ("PACKAGE_STRING")\n", sizeof szStr);
        !           163:                write(h, szStr, strlen(szStr));
        !           164: 
        !           165:                ret = 0;        /* new key created */
1.1       misho     166:        }
                    167:        close(h);
                    168: 
1.3     ! misho     169:        (*Sess)->type = id;
1.1       misho     170:        return ret;
                    171: }
                    172: 
                    173: /*
                    174:  * freeSession() Free allocated memory for session item and delete session file if present name
                    175:  * @csFName = Session filename for delete, if NULL nothing delete
                    176:  * @Sess = Session item
                    177: */
1.3     ! misho     178: inline void
        !           179: freeSession(const char *csFName, tagSess ** __restrict Sess)
1.1       misho     180: {
1.3     ! misho     181:        assert(Sess);
        !           182:        if (!Sess)
        !           183:                return;
        !           184: 
        !           185:        (*Sess)->type = SHARED_UNKNOWN;
1.1       misho     186:        if (csFName)
                    187:                unlink(csFName);
                    188:        if (*Sess)
                    189:                free(*Sess);
                    190:        *Sess = NULL;
                    191: }
                    192: 
                    193: 
                    194: /*
                    195:  * map_createSession() MMAP Created session and allocated resources
                    196:  * @csFName = Session name for identified
                    197:  * @cnSeed = Seed for securing key
                    198:  * @cnSize = Allocated shared memory size in bytes
                    199:  * @Sess = Session item
                    200:  * return: 0 Ok successful, -1 error: not allocated resources
                    201: */
1.3     ! misho     202: int
        !           203: map_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess)
1.1       misho     204: {
1.3     ! misho     205:        int ret = 0, id = SHARED_MAP;
        !           206:        char szSName[2][FILENAME_MAX];
1.1       misho     207: 
1.3     ! misho     208:        ret = initSession(&id, csFName, Sess);
1.1       misho     209:        if (ret == -1 || !*Sess)
                    210:                return -1;
                    211: 
1.3     ! misho     212:        /* genkey */
1.1       misho     213:        (*Sess)->key = ftok(csFName, cnSeed);
                    214:        if ((*Sess)->key == -1) {
                    215:                LOGERR;
                    216:                freeSession(csFName, Sess);
                    217:                return -1;
                    218:        }
                    219: 
1.3     ! misho     220:        /* build semaphore & shared memory name */
        !           221:        memset(szSName, 0, sizeof szSName);
        !           222:        snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) (*Sess)->key);
        !           223:        snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", csFName, (u_int) (*Sess)->key);
1.1       misho     224: 
1.3     ! misho     225:        /* create semaphore & add 1 */
1.2       misho     226:        (*Sess)->id.sid = sem_open(szSName[0], O_CREAT, MEM_MODE);
1.1       misho     227:        if ((*Sess)->id.sid == SEM_FAILED) {
                    228:                LOGERR;
                    229:                map_destroySession(csFName, Sess);
                    230:                return -1;
                    231:        } else
                    232:                sem_post((*Sess)->id.sid);
                    233: 
1.3     ! misho     234:        /* create file for shared memory storage */
1.2       misho     235:        (*Sess)->mem.fd = open(szSName[1], O_RDWR | O_CREAT, MEM_MODE);
1.1       misho     236:        if ((*Sess)->mem.fd == -1) {
                    237:                LOGERR;
                    238:                map_destroySession(csFName, Sess);
                    239:                return -1;
                    240:        }
1.3     ! misho     241:        /* if is new shared memory session, fill file with zeros */
1.1       misho     242:        if (!ret) {
1.3     ! misho     243:                if (lseek((*Sess)->mem.fd, cnSize - 1, SEEK_SET) == -1) {
1.1       misho     244:                        LOGERR;
                    245:                        map_destroySession(csFName, Sess);
                    246:                        return -1;
1.3     ! misho     247:                } else
        !           248:                        write((*Sess)->mem.fd, "", 1);
        !           249:                lseek((*Sess)->mem.fd, 0, SEEK_SET);
1.1       misho     250:        }
                    251:        (*Sess)->eom = cnSize;
                    252: 
                    253:        return ret;
                    254: }
                    255: 
                    256: /*
                    257:  * map_destroySession() MMAP free shared resources
                    258:  * @csFName = Session name for delete
                    259:  * @Sess = Session item
                    260: */
1.3     ! misho     261: void
        !           262: map_destroySession(const char *csFName, tagSess ** __restrict Sess)
1.1       misho     263: {
                    264:        int flg = 1;
1.3     ! misho     265:        char szSName[2][FILENAME_MAX];
1.1       misho     266: 
1.3     ! misho     267:        assert(Sess);
        !           268:        if (!Sess || !*Sess)
1.1       misho     269:                return;
                    270: 
1.3     ! misho     271:        memset(szSName, 0, sizeof szSName);
        !           272:        snprintf(szSName[0], MAX_SEMNAME, "/%X.ANS", (u_int) (*Sess)->key);
        !           273:        snprintf(szSName[1], FILENAME_MAX, "%s-%x.ANM", csFName, (u_int) (*Sess)->key);
1.1       misho     274: 
                    275:        if ((*Sess)->id.sid != SEM_FAILED) {
                    276:                if (sem_close((*Sess)->id.sid) == -1)
                    277:                        flg = 0;
                    278:                if (sem_unlink(szSName[0]) == -1)
                    279:                        /*flg = 0*/;
                    280:        }
                    281:        if ((*Sess)->mem.fd != -1) {
                    282:                if (close((*Sess)->mem.fd) == -1)
                    283:                        flg = 0;
                    284:                if (unlink(szSName[1]) == -1)
                    285:                        /*flg = 0*/;
                    286:        }
                    287:        (*Sess)->eom ^= (*Sess)->eom;
                    288: 
                    289:        freeSession(flg ? csFName : NULL, Sess);
                    290: }
                    291: 
                    292: /*
                    293:  * ipc_createSession() IPC Created session and allocated resources
                    294:  * @csFName = Session name for identified
                    295:  * @cnSeed = Seed for securing key
                    296:  * @cnSize = Allocated shared memory size in bytes
                    297:  * @Sess = Session item
                    298:  * return: 0 Ok successful, -1 error: not allocated resources
                    299: */
1.3     ! misho     300: int
        !           301: ipc_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess)
1.1       misho     302: {
1.3     ! misho     303:        int ret = 0, id = SHARED_IPC;
1.1       misho     304:        union semun sems;
                    305: 
1.3     ! misho     306:        ret = initSession(&id, csFName, Sess);
1.1       misho     307:        if (ret == -1 || !*Sess)
                    308:                return -1;
                    309: 
1.3     ! misho     310:        /* genkey */
1.1       misho     311:        (*Sess)->key = ftok(csFName, cnSeed);
                    312:        if ((*Sess)->key == -1) {
                    313:                LOGERR;
                    314:                freeSession(csFName, Sess);
                    315:                return -1;
                    316:        }
                    317: 
1.3     ! misho     318:        /* create semaphore */
1.2       misho     319:        (*Sess)->id.semid = semget((*Sess)->key, 1, MEM_MODE | IPC_CREAT);
1.1       misho     320:        if ((*Sess)->id.semid == -1) {
                    321:                LOGERR;
                    322:                ipc_destroySession(csFName, Sess);
                    323:                return -1;
                    324:        }
1.3     ! misho     325:        /* if is new shared memory session, init sempahore with 1 */
1.1       misho     326:        if (!ret) {
                    327:                sems.val = 1;
                    328:                if (semctl((*Sess)->id.semid, 0, SETVAL, sems) == -1) {
                    329:                        LOGERR;
                    330:                        ipc_destroySession(csFName, Sess);
                    331:                        return -1;
                    332:                }
                    333:        }
                    334: 
1.3     ! misho     335:        /* create shared memory object */
1.2       misho     336:        (*Sess)->mem.shmid = shmget((*Sess)->key, cnSize, MEM_MODE | IPC_CREAT);
1.1       misho     337:        if ((*Sess)->mem.shmid == -1) {
                    338:                LOGERR;
                    339:                ipc_destroySession(csFName, Sess);
                    340:                return -1;
                    341:        }
                    342:        (*Sess)->eom = cnSize;
                    343: 
                    344:        return ret;
                    345: }
                    346: 
                    347: /*
                    348:  * ipc_destroySession() IPC free shared resources
                    349:  * @csFName = Session name for delete
                    350:  * @Sess = Session item
                    351: */
1.3     ! misho     352: void
        !           353: ipc_destroySession(const char *csFName, tagSess ** __restrict Sess)
1.1       misho     354: {
                    355:        int flg = 1;
                    356:        union semun sems;
                    357:        struct shmid_ds ds;
                    358: 
1.3     ! misho     359:        assert(Sess);
        !           360:        if (!Sess || !*Sess)
1.1       misho     361:                return;
                    362: 
                    363:        if ((*Sess)->id.semid != -1)
                    364:                if (semctl((*Sess)->id.semid, 0, IPC_RMID, &sems) == -1)
                    365:                        flg = 0;
                    366:        if ((*Sess)->mem.shmid != -1)
                    367:                if (shmctl((*Sess)->mem.shmid, IPC_RMID, &ds) == -1)
                    368:                        flg = 0;
                    369:        (*Sess)->eom ^= (*Sess)->eom;
                    370: 
                    371:        freeSession(flg ? csFName : NULL, Sess);
                    372: }
                    373: 
                    374: 
                    375: /*
                    376:  * map_attachSession() MMAP Attach to shared memory & return begin address
                    377:  * @s = Session item
                    378:  * @procMem = Custom start address (optionl) *default must be 0*
                    379:  * return: NULL failed attach, !=NULL begin address of memory
                    380: */
1.3     ! misho     381: inline void *
        !           382: map_attachSession(tagSess * __restrict s, void *procMem)
1.1       misho     383: {
                    384:        struct stat sb;
                    385: 
                    386:        if (!s)
                    387:                return NULL;
                    388: 
1.3     ! misho     389:        /* Learn size of shared memory block */
1.1       misho     390:        sync();
                    391:        if (fstat(s->mem.fd, &sb) == -1) {
                    392:                LOGERR;
                    393:                return NULL;
                    394:        } else
                    395:                s->eom = sb.st_size;
                    396: 
1.3     ! misho     397:        /* attach to memory */
1.1       misho     398:        s->addr = mmap(procMem, s->eom, PROT_READ | PROT_WRITE, MAP_SHARED, s->mem.fd, 0);
                    399:        if (s->addr == MAP_FAILED) {
                    400:                LOGERR;
                    401:                s->addr = NULL;
                    402:        }
                    403: 
                    404:        return s->addr;
                    405: }
                    406: 
                    407: /*
                    408:  * map_detachSession() MMAP Detach from shared memory
                    409:  * @s = Session item
                    410: */
1.3     ! misho     411: inline void
        !           412: map_detachSession(tagSess * __restrict s)
1.1       misho     413: {
                    414:        if (!s)
                    415:                return;
                    416: 
                    417:        msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);
                    418: 
                    419:        if (s->addr && s->eom) {
                    420:                munmap(s->addr, s->eom);
                    421:                s->addr = NULL;
                    422:        }
                    423: }
                    424: 
                    425: /*
                    426:  * ipc_attachSession() IPC Attach to shared memory & return begin address
                    427:  * @s = Session item
                    428:  * @procMem = Custom start address (optionl) *default must be 0*
                    429:  * return: NULL failed attach, !=NULL begin address of memory
                    430: */
1.3     ! misho     431: inline void *
        !           432: ipc_attachSession(tagSess * __restrict s, void *procMem)
1.1       misho     433: {
                    434:        if (!s)
                    435:                return NULL;
                    436: 
                    437:        s->addr = shmat(s->mem.shmid, procMem, 0);
                    438:        if (s->addr == (void*) -1) {
                    439:                LOGERR;
                    440:                s->addr = NULL;
                    441:        }
                    442: 
                    443:        return s->addr;
                    444: }
                    445: 
                    446: /*
                    447:  * ipc_detachSession() IPC Detach from shared memory
                    448:  * @s = Session item
                    449: */
1.3     ! misho     450: inline void
        !           451: ipc_detachSession(tagSess * __restrict s)
1.1       misho     452: {
                    453:        if (!s)
                    454:                return;
                    455: 
                    456:        if (s->addr) {
                    457:                shmdt(s->addr);
                    458:                s->addr = NULL;
                    459:        }
                    460: }
                    461: 
1.2       misho     462: /*
                    463:  * isAttached() Check for mapped/(attached) shared memory
                    464:  * @s = Session item
                    465:  * return: -1 null session item, 0 not attached, 1 attached memory
                    466: */
1.3     ! misho     467: inline int
        !           468: isAttached(tagSess * __restrict s)
1.2       misho     469: {
                    470:        if (!s)
                    471:                return -1;
                    472: 
                    473:        return (s->addr ? 1 : 0);
                    474: }
                    475: 
1.1       misho     476: 
                    477: /*
                    478:  * map_notSemaphore() MMAP negative block if semaphore isn`t signaled
                    479:  * @s = Session item
                    480: */
1.3     ! misho     481: inline void
        !           482: map_notSemaphore(tagSess * __restrict s)
1.1       misho     483: {
                    484:        int i = -1;
                    485: 
                    486:        if (!s)
                    487:                return;
                    488: 
                    489:        sem_getvalue(s->id.sid, &i);
                    490:        for (;i > 0; i--)
                    491:                sem_wait(s->id.sid);
                    492: }
                    493: 
                    494: /*
                    495:  * map_isSemaphored() MMAP Check semaphore
                    496:  * @s = Session item
                    497:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
                    498: */
1.3     ! misho     499: inline int
        !           500: map_isSemaphored(tagSess * __restrict s)
1.1       misho     501: {
                    502:        int val = -1;
                    503: 
                    504:        if (!s)
                    505:                return -1;
                    506: 
                    507:        sem_getvalue(s->id.sid, &val);
                    508:        return val ? 0 : 1;
                    509: }
                    510: 
                    511: /*
                    512:  * map_addSemaphore() MMAP unblock semaphore, increment semaphore
                    513:  * @s = Session item
                    514:  * return: 0 Ok, -1 error: can`t increment 
                    515: */
1.3     ! misho     516: inline int
        !           517: map_addSemaphore(tagSess * __restrict s)
1.1       misho     518: {
                    519:        if (!s)
                    520:                return -1;
                    521: 
                    522:        return sem_post(s->id.sid);
                    523: }
                    524: 
                    525: /*
                    526:  * map_decSemaphore() MMAP block semaphore, decrement semaphore
                    527:  * @s = Session item
                    528:  * return: 0 Ok, -1 error: can`t decrement 
                    529: */
1.3     ! misho     530: inline int
        !           531: map_decSemaphore(tagSess * __restrict s)
1.1       misho     532: {
                    533:        if (!s)
                    534:                return -1;
                    535: 
                    536:        return sem_wait(s->id.sid);
                    537: }
                    538: 
                    539: /*
                    540:  * ipc_notSemaphore() IPC negative block if semaphore isn`t signaled
                    541:  * @s = Session item
                    542: */
1.3     ! misho     543: inline void
        !           544: ipc_notSemaphore(tagSess * __restrict s)
1.1       misho     545: {
                    546:        struct sembuf sb = { 0, 0, 0 };
                    547: 
                    548:        if (s)
                    549:                semop(s->id.semid, &sb, 1);
                    550: }
                    551: 
                    552: /*
                    553:  * ipc_isSemaphored() IPC Check semaphore
                    554:  * @s = Session item
                    555:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
                    556: */
1.3     ! misho     557: inline int
        !           558: ipc_isSemaphored(tagSess * __restrict s)
1.1       misho     559: {
                    560:        struct sembuf sb = { 0, 0, IPC_NOWAIT };
                    561: 
                    562:        if (!s)
                    563:                return -1;
                    564: 
                    565:        return semop(s->id.semid, &sb, 1) + 1;
                    566: }
                    567: 
                    568: /*
                    569:  * ipc_addSemaphore() IPC unblock semaphore, increment semaphore
                    570:  * @s = Session item
                    571:  * return: 0 Ok, -1 error: can`t increment 
                    572: */
1.3     ! misho     573: inline int
        !           574: ipc_addSemaphore(tagSess * __restrict s)
1.1       misho     575: {
                    576:        struct sembuf sb = { 0, 1, 0 };
                    577: 
                    578:        if (!s)
                    579:                return -1;
                    580: 
                    581:        return semop(s->id.semid, &sb, 1);
                    582: }
                    583: 
                    584: /*
                    585:  * ipc_decSemaphore() IPC block semaphore, decrement semaphore
                    586:  * @s = Session item
                    587:  * return: 0 Ok, -1 error: can`t decrement 
                    588: */
1.3     ! misho     589: inline int
        !           590: ipc_decSemaphore(tagSess * __restrict s)
1.1       misho     591: {
                    592:        struct sembuf sb = { 0, -1, 0 };
                    593: 
                    594:        if (!s)
                    595:                return -1;
                    596: 
                    597:        return semop(s->id.semid, &sb, 1);
                    598: }

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