File:  [ELWIX - Embedded LightWeight unIX -] / libaitsess / src / aitsess.c
Revision 1.1.1.1.2.2: download - view: text, annotated - select for diffs - revision graph
Mon Oct 13 18:22:01 2008 UTC (15 years, 8 months ago) by misho
Branches: sess2_0
Diff to: branchpoint 1.1.1.1: preferred, unified
add new func & change attach

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

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