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>