Annotation of libaitsess/src/aitsess.c, revision 1.1.1.1.2.2
1.1.1.1.2.1 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.1.1.1.2.2! misho 6: * $Id: aitsess.c,v 1.1.1.1.2.1 2008/09/30 20:19:48 misho Exp $
1.1.1.1.2.1 misho 7: *
8: *************************************************************************/
1.1 misho 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:
1.1.1.1.2.2! misho 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:
1.1 misho 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>