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>