Annotation of libaitsess/src/aitsess.c, revision 1.1.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>