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

1.1     ! misho       1: #include "global.h"
        !             2: #include "aitsess.h"
        !             3: 
        !             4: 
        !             5: #pragma GCC visibility push(hidden)
        !             6: 
        !             7: int sessErrno;
        !             8: char sessError[MAX_STR + 1];
        !             9: 
        !            10: #pragma GCC visibility pop
        !            11: 
        !            12: // -----------------------------------------------------------
        !            13: 
        !            14: // Error maintenance functions ...
        !            15: 
        !            16: // sess_GetErrno() Get error code of last operation
        !            17: inline int sess_GetErrno()
        !            18: {
        !            19:        return sessErrno;
        !            20: }
        !            21: // sess_GetError() Get error text of last operation
        !            22: inline const char *sess_GetError()
        !            23: {
        !            24:        return sessError;
        !            25: }
        !            26: // sessDbg() Debug/Logging operations
        !            27: static inline int sessDbg(FILE *f, char *fmt, ...)
        !            28: {
        !            29:        int ret = 0;
        !            30:        va_list lst;
        !            31: 
        !            32:        va_start(lst, fmt);
        !            33:        ret = vfprintf(f, fmt, lst);
        !            34:        va_end(lst);
        !            35: 
        !            36:        return ret;
        !            37: }
        !            38: 
        !            39: // -----------------------------------------------------------
        !            40: 
        !            41: /*
        !            42:  * initSession() Initializing session structure, if session file not exists creating with specified tech
        !            43:  * @cnID = Technology using in session. SHARED_IPC IPC tech; SHARED_MAP BSD MemoryMap tech
        !            44:  * @csFName = Session filename for build key and identified
        !            45:  * @Sess = Session item
        !            46:  * return: 0 OK new key created, -1 error: no memory or file not created, 1 OK key finded
        !            47: */
        !            48: inline int initSession(const int cnID, const char *csFName, tagSess ** __restrict Sess)
        !            49: {
        !            50:        int h, ret = 0;
        !            51:        char szStr[MAX_STR + 1];
        !            52: 
        !            53:        if (!*Sess) {
        !            54:                *Sess = malloc(sizeof(tagSess));
        !            55:                if (!*Sess) {
        !            56:                        LOGERR;
        !            57:                        return -1;
        !            58:                }
        !            59:        }
        !            60:        memset(*Sess, 0, sizeof(tagSess));
        !            61: 
        !            62:        // If key file exist, session already connected
        !            63:        if (!access(csFName, F_OK))
        !            64:                ret = 1;
        !            65:        // Build new key & new session
        !            66:        h = open(csFName, O_WRONLY | O_CREAT, 0640);
        !            67:        if (h == -1) {
        !            68:                LOGERR;
        !            69:                free(*Sess);
        !            70:                return -1;
        !            71:        }
        !            72: 
        !            73:        bzero(szStr, MAX_STR + 1);
        !            74:        switch (cnID) {
        !            75:                case SHARED_IPC:
        !            76:                        strcpy(szStr, "IPC@");
        !            77:                        break;
        !            78:                case SHARED_MAP:
        !            79:                        strcpy(szStr, "MAP@");
        !            80:                        break;
        !            81:                default:
        !            82:                        errno = EPROTONOSUPPORT;
        !            83:                        LOGERR;
        !            84: 
        !            85:                        close(h);
        !            86:                        unlink(csFName);
        !            87:                        free(*Sess);
        !            88:                        return -1;
        !            89:        }
        !            90:        strcat(szStr, "AN_Session ver");
        !            91:        strcat(szStr, "\n");
        !            92:        write(h, szStr, strlen(szStr));
        !            93:        close(h);
        !            94: 
        !            95:        (*Sess)->type = cnID;
        !            96:        return ret;
        !            97: }
        !            98: 
        !            99: /*
        !           100:  * freeSession() Free allocated memory for session item and delete session file if present name
        !           101:  * @csFName = Session filename for delete, if NULL nothing delete
        !           102:  * @Sess = Session item
        !           103: */
        !           104: inline void freeSession(const char *csFName, tagSess ** __restrict Sess)
        !           105: {
        !           106:        (*Sess)->type ^= (*Sess)->type;
        !           107:        if (csFName)
        !           108:                unlink(csFName);
        !           109:        if (*Sess)
        !           110:                free(*Sess);
        !           111:        *Sess = NULL;
        !           112: }
        !           113: 
        !           114: 
        !           115: /*
        !           116:  * map_createSession() MMAP Created session and allocated resources
        !           117:  * @csFName = Session name for identified
        !           118:  * @cnSeed = Seed for securing key
        !           119:  * @cnSize = Allocated shared memory size in bytes
        !           120:  * @Sess = Session item
        !           121:  * return: 0 Ok successful, -1 error: not allocated resources
        !           122: */
        !           123: int map_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess)
        !           124: {
        !           125:        int ret = 0;
        !           126:        char szSName[2][FILENAME_MAX + 1];
        !           127:        void *mem;
        !           128: 
        !           129:        ret = initSession(SHARED_MAP, csFName, Sess);
        !           130:        if (ret == -1 || !*Sess)
        !           131:                return -1;
        !           132: 
        !           133:        // genkey
        !           134:        (*Sess)->key = ftok(csFName, cnSeed);
        !           135:        if ((*Sess)->key == -1) {
        !           136:                LOGERR;
        !           137:                freeSession(csFName, Sess);
        !           138:                return -1;
        !           139:        }
        !           140: 
        !           141:        // build semaphore & shared memory name
        !           142:        memset(szSName, 0, (FILENAME_MAX + 1) * 2);
        !           143:        snprintf(szSName[0], MAX_SEMNAME + 1, "/%X.ANS", (u_int) (*Sess)->key);
        !           144:        snprintf(szSName[1], FILENAME_MAX + 1, "%s-%x.ANM", csFName, (u_int) (*Sess)->key);
        !           145: 
        !           146:        mem = malloc(cnSize);
        !           147:        if (!mem) {
        !           148:                LOGERR;
        !           149:                freeSession(csFName, Sess);
        !           150:                return -1;
        !           151:        } else
        !           152:                memset(mem, 0, cnSize);
        !           153: 
        !           154:        // create semaphore & add 1
        !           155:        (*Sess)->id.sid = sem_open(szSName[0], O_CREAT, 0644);
        !           156:        if ((*Sess)->id.sid == SEM_FAILED) {
        !           157:                LOGERR;
        !           158:                map_destroySession(csFName, Sess);
        !           159:                free(mem);
        !           160:                return -1;
        !           161:        } else
        !           162:                sem_post((*Sess)->id.sid);
        !           163: 
        !           164:        // create file for shared memory storage
        !           165:        (*Sess)->mem.fd = open(szSName[1], O_RDWR | O_CREAT, 0644);
        !           166:        if ((*Sess)->mem.fd == -1) {
        !           167:                LOGERR;
        !           168:                map_destroySession(csFName, Sess);
        !           169:                free(mem);
        !           170:                return -1;
        !           171:        }
        !           172:        // if is new shared memory session, fill file with zeros
        !           173:        if (!ret) {
        !           174:                if (write((*Sess)->mem.fd, mem, cnSize) != cnSize) {
        !           175:                        LOGERR;
        !           176:                        map_destroySession(csFName, Sess);
        !           177:                        free(mem);
        !           178:                        return -1;
        !           179:                }
        !           180:                if (lseek((*Sess)->mem.fd, 0, SEEK_SET)) {
        !           181:                        LOGERR;
        !           182:                        map_destroySession(csFName, Sess);
        !           183:                        free(mem);
        !           184:                        return -1;
        !           185:                }
        !           186:        }
        !           187:        (*Sess)->eom = cnSize;
        !           188: 
        !           189:        free(mem);
        !           190:        return ret;
        !           191: }
        !           192: 
        !           193: /*
        !           194:  * map_destroySession() MMAP free shared resources
        !           195:  * @csFName = Session name for delete
        !           196:  * @Sess = Session item
        !           197: */
        !           198: void map_destroySession(const char *csFName, tagSess ** __restrict Sess)
        !           199: {
        !           200:        int flg = 1;
        !           201:        char szSName[2][FILENAME_MAX + 1];
        !           202: 
        !           203:        if (!*Sess)
        !           204:                return;
        !           205: 
        !           206:        bzero(szSName, (FILENAME_MAX + 1) * 2);
        !           207:        snprintf(szSName[0], MAX_SEMNAME + 1, "/%X.ANS", (u_int) (*Sess)->key);
        !           208:        snprintf(szSName[1], FILENAME_MAX + 1, "%s-%x.ANM", csFName, (u_int) (*Sess)->key);
        !           209: 
        !           210:        if ((*Sess)->id.sid != SEM_FAILED) {
        !           211:                if (sem_close((*Sess)->id.sid) == -1)
        !           212:                        flg = 0;
        !           213: 
        !           214:                if (sem_unlink(szSName[0]) == -1)
        !           215:                        /*flg = 0*/;
        !           216:        }
        !           217:        if ((*Sess)->mem.fd != -1) {
        !           218:                if (close((*Sess)->mem.fd) == -1)
        !           219:                        flg = 0;
        !           220: 
        !           221:                if (unlink(szSName[1]) == -1)
        !           222:                        /*flg = 0*/;
        !           223:        }
        !           224:        (*Sess)->eom ^= (*Sess)->eom;
        !           225: 
        !           226:        freeSession(flg ? csFName : NULL, Sess);
        !           227: }
        !           228: 
        !           229: /*
        !           230:  * ipc_createSession() IPC Created session and allocated resources
        !           231:  * @csFName = Session name for identified
        !           232:  * @cnSeed = Seed for securing key
        !           233:  * @cnSize = Allocated shared memory size in bytes
        !           234:  * @Sess = Session item
        !           235:  * return: 0 Ok successful, -1 error: not allocated resources
        !           236: */
        !           237: int ipc_createSession(const char *csFName, const int cnSeed, const u_int cnSize, tagSess ** __restrict Sess)
        !           238: {
        !           239:        int ret = 0;
        !           240:        union semun sems;
        !           241: 
        !           242:        ret = initSession(SHARED_IPC, csFName, Sess);
        !           243:        if (ret == -1 || !*Sess)
        !           244:                return -1;
        !           245: 
        !           246:        // genkey
        !           247:        (*Sess)->key = ftok(csFName, cnSeed);
        !           248:        if ((*Sess)->key == -1) {
        !           249:                LOGERR;
        !           250:                freeSession(csFName, Sess);
        !           251:                return -1;
        !           252:        }
        !           253: 
        !           254:        // create semaphore
        !           255:        (*Sess)->id.semid = semget((*Sess)->key, 1, 0644 | IPC_CREAT);
        !           256:        if ((*Sess)->id.semid == -1) {
        !           257:                LOGERR;
        !           258:                ipc_destroySession(csFName, Sess);
        !           259:                return -1;
        !           260:        }
        !           261:        // if is new shared memory session, init sempahore with 1
        !           262:        if (!ret) {
        !           263:                sems.val = 1;
        !           264:                if (semctl((*Sess)->id.semid, 0, SETVAL, sems) == -1) {
        !           265:                        LOGERR;
        !           266:                        ipc_destroySession(csFName, Sess);
        !           267:                        return -1;
        !           268:                }
        !           269:        }
        !           270: 
        !           271:        // create shared memory object
        !           272:        (*Sess)->mem.shmid = shmget((*Sess)->key, cnSize, 0644 | IPC_CREAT);
        !           273:        if ((*Sess)->mem.shmid == -1) {
        !           274:                LOGERR;
        !           275:                ipc_destroySession(csFName, Sess);
        !           276:                return -1;
        !           277:        }
        !           278:        (*Sess)->eom = cnSize;
        !           279: 
        !           280:        return ret;
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * ipc_destroySession() IPC free shared resources
        !           285:  * @csFName = Session name for delete
        !           286:  * @Sess = Session item
        !           287: */
        !           288: void ipc_destroySession(const char *csFName, tagSess ** __restrict Sess)
        !           289: {
        !           290:        int flg = 1;
        !           291:        union semun sems;
        !           292:        struct shmid_ds ds;
        !           293: 
        !           294:        if (!*Sess)
        !           295:                return;
        !           296: 
        !           297:        if ((*Sess)->id.semid != -1)
        !           298:                if (semctl((*Sess)->id.semid, 0, IPC_RMID, &sems) == -1)
        !           299:                        flg = 0;
        !           300:        if ((*Sess)->mem.shmid != -1)
        !           301:                if (shmctl((*Sess)->mem.shmid, IPC_RMID, &ds) == -1)
        !           302:                        flg = 0;
        !           303:        (*Sess)->eom ^= (*Sess)->eom;
        !           304: 
        !           305:        freeSession(flg ? csFName : NULL, Sess);
        !           306: }
        !           307: 
        !           308: 
        !           309: /*
        !           310:  * map_attachSession() MMAP Attach to shared memory & return begin address
        !           311:  * @s = Session item
        !           312:  * @procMem = Custom start address (optionl) *default must be 0*
        !           313:  * return: NULL failed attach, !=NULL begin address of memory
        !           314: */
        !           315: inline void *map_attachSession(tagSess * __restrict s, void *procMem)
        !           316: {
        !           317:        struct stat sb;
        !           318: 
        !           319:        if (!s)
        !           320:                return NULL;
        !           321: 
        !           322:        // Learn size of shared memory block
        !           323:        sync();
        !           324:        if (fstat(s->mem.fd, &sb) == -1) {
        !           325:                LOGERR;
        !           326:                return NULL;
        !           327:        } else
        !           328:                s->eom = sb.st_size;
        !           329: 
        !           330:        // attach to memory
        !           331:        s->addr = mmap(procMem, s->eom, PROT_READ | PROT_WRITE, MAP_SHARED, s->mem.fd, 0);
        !           332:        if (s->addr == MAP_FAILED) {
        !           333:                LOGERR;
        !           334:                s->addr = NULL;
        !           335:        }
        !           336: 
        !           337:        return s->addr;
        !           338: }
        !           339: 
        !           340: /*
        !           341:  * map_detachSession() MMAP Detach from shared memory
        !           342:  * @s = Session item
        !           343: */
        !           344: inline void map_detachSession(tagSess * __restrict s)
        !           345: {
        !           346:        if (!s)
        !           347:                return;
        !           348: 
        !           349:        msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);
        !           350: 
        !           351:        if (s->addr && s->eom) {
        !           352:                munmap(s->addr, s->eom);
        !           353:                s->addr = NULL;
        !           354:        }
        !           355: }
        !           356: 
        !           357: /*
        !           358:  * ipc_attachSession() IPC Attach to shared memory & return begin address
        !           359:  * @s = Session item
        !           360:  * @procMem = Custom start address (optionl) *default must be 0*
        !           361:  * return: NULL failed attach, !=NULL begin address of memory
        !           362: */
        !           363: inline void *ipc_attachSession(tagSess * __restrict s, void *procMem)
        !           364: {
        !           365:        if (!s)
        !           366:                return NULL;
        !           367: 
        !           368:        s->addr = shmat(s->mem.shmid, procMem, 0);
        !           369:        if (s->addr == (void*) -1) {
        !           370:                LOGERR;
        !           371:                s->addr = NULL;
        !           372:        }
        !           373: 
        !           374:        return s->addr;
        !           375: }
        !           376: 
        !           377: /*
        !           378:  * ipc_detachSession() IPC Detach from shared memory
        !           379:  * @s = Session item
        !           380: */
        !           381: inline void ipc_detachSession(tagSess * __restrict s)
        !           382: {
        !           383:        if (!s)
        !           384:                return;
        !           385: 
        !           386:        if (s->addr) {
        !           387:                shmdt(s->addr);
        !           388:                s->addr = NULL;
        !           389:        }
        !           390: }
        !           391: 
        !           392: 
        !           393: /*
        !           394:  * map_notSemaphore() MMAP negative block if semaphore isn`t signaled
        !           395:  * @s = Session item
        !           396: */
        !           397: inline void map_notSemaphore(tagSess * __restrict s)
        !           398: {
        !           399:        int i = -1;
        !           400: 
        !           401:        if (!s)
        !           402:                return;
        !           403: 
        !           404:        sem_getvalue(s->id.sid, &i);
        !           405:        for (;i > 0; i--)
        !           406:                sem_wait(s->id.sid);
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * map_isSemaphored() MMAP Check semaphore
        !           411:  * @s = Session item
        !           412:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
        !           413: */
        !           414: inline int map_isSemaphored(tagSess * __restrict s)
        !           415: {
        !           416:        int val = -1;
        !           417: 
        !           418:        if (!s)
        !           419:                return -1;
        !           420: 
        !           421:        sem_getvalue(s->id.sid, &val);
        !           422:        return val ? 0 : 1;
        !           423: }
        !           424: 
        !           425: /*
        !           426:  * map_addSemaphore() MMAP unblock semaphore, increment semaphore
        !           427:  * @s = Session item
        !           428:  * return: 0 Ok, -1 error: can`t increment 
        !           429: */
        !           430: inline int map_addSemaphore(tagSess * __restrict s)
        !           431: {
        !           432:        if (!s)
        !           433:                return -1;
        !           434: 
        !           435:        return sem_post(s->id.sid);
        !           436: }
        !           437: 
        !           438: /*
        !           439:  * map_decSemaphore() MMAP block semaphore, decrement semaphore
        !           440:  * @s = Session item
        !           441:  * return: 0 Ok, -1 error: can`t decrement 
        !           442: */
        !           443: inline int map_decSemaphore(tagSess * __restrict s)
        !           444: {
        !           445:        if (!s)
        !           446:                return -1;
        !           447: 
        !           448:        return sem_wait(s->id.sid);
        !           449: }
        !           450: 
        !           451: /*
        !           452:  * ipc_notSemaphore() IPC negative block if semaphore isn`t signaled
        !           453:  * @s = Session item
        !           454: */
        !           455: inline void ipc_notSemaphore(tagSess * __restrict s)
        !           456: {
        !           457:        struct sembuf sb = { 0, 0, 0 };
        !           458: 
        !           459:        if (s)
        !           460:                semop(s->id.semid, &sb, 1);
        !           461: }
        !           462: 
        !           463: /*
        !           464:  * ipc_isSemaphored() IPC Check semaphore
        !           465:  * @s = Session item
        !           466:  * return: -1 error: can`t return semaphore, 0 = false, 1 = true
        !           467: */
        !           468: inline int ipc_isSemaphored(tagSess * __restrict s)
        !           469: {
        !           470:        struct sembuf sb = { 0, 0, IPC_NOWAIT };
        !           471: 
        !           472:        if (!s)
        !           473:                return -1;
        !           474: 
        !           475:        return semop(s->id.semid, &sb, 1) + 1;
        !           476: }
        !           477: 
        !           478: /*
        !           479:  * ipc_addSemaphore() IPC unblock semaphore, increment semaphore
        !           480:  * @s = Session item
        !           481:  * return: 0 Ok, -1 error: can`t increment 
        !           482: */
        !           483: inline int ipc_addSemaphore(tagSess * __restrict s)
        !           484: {
        !           485:        struct sembuf sb = { 0, 1, 0 };
        !           486: 
        !           487:        if (!s)
        !           488:                return -1;
        !           489: 
        !           490:        return semop(s->id.semid, &sb, 1);
        !           491: }
        !           492: 
        !           493: /*
        !           494:  * ipc_decSemaphore() IPC block semaphore, decrement semaphore
        !           495:  * @s = Session item
        !           496:  * return: 0 Ok, -1 error: can`t decrement 
        !           497: */
        !           498: inline int ipc_decSemaphore(tagSess * __restrict s)
        !           499: {
        !           500:        struct sembuf sb = { 0, -1, 0 };
        !           501: 
        !           502:        if (!s)
        !           503:                return -1;
        !           504: 
        !           505:        return semop(s->id.semid, &sb, 1);
        !           506: }

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