1 #include "csf.h"
2 #include "csfimpl.h"
3
4 #include <stdlib.h>
5
6 /***************/
7 /* EXTERNALS */
8 /***************/
9
10 static MAP **mapList = NULL;
11 static size_t mapListLen = 4;
12
13 /*********************/
14 /* LOCAL DEFINITIONS */
15 /*********************/
16
17 /**********************/
18 /* LOCAL DECLARATIONS */
19 /**********************/
20
21 /******************/
22 /* IMPLEMENTATION */
23 /******************/
24
25
26 /* close all open maps at exit (LIBRARY_INTERNAL)
27 * passed through atexit to c-library
28 * exit code
29 */
CsfCloseCsfKernel(void)30 static void CsfCloseCsfKernel(void)
31 {
32 size_t i;
33
34 for(i = 0; i < mapListLen; i++)
35 if(mapList[i] != NULL)
36 if(Mclose(mapList[i]))
37 (void)fprintf(stderr,"CSF_INTERNAL_ERROR: unable to close %s at exit\n",
38 mapList[i]->fileName);
39 CSF_FREE(mapList);
40 mapList = NULL;
41 }
42
43 /* boot the CSF runtime library (LIBRARY_INTERNAL)
44 * CsfBootCsfKernel creates the mapList and adds the function to
45 * close all files at a system exit
46 *
47 * NOTE
48 * Note that CsfBootCsfKernel never returns if there isn't enough
49 * memory to allocate an array of mapListLen pointers, or if
50 * the atexit() call fails
51 */
CsfBootCsfKernel(void)52 void CsfBootCsfKernel(void)
53 {
54 POSTCOND(mapList == NULL);
55
56 mapList = (MAP **)calloc(mapListLen,sizeof(MAP *));
57 if (mapList == NULL) {
58 (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Not enough memory to use CSF-files\n");
59 exit(1);
60 }
61
62 if (atexit(CsfCloseCsfKernel)) {
63 (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Impossible to close CSF-files automatically at exit\n");
64 exit(1);
65 }
66 }
67
68 /* check if the kernel is booted (LIBRARY_INTERNAL)
69 * returns 0 if not, nonzero if already booted
70 */
CsfIsBootedCsfKernel(void)71 int CsfIsBootedCsfKernel(void)
72 {
73 return(mapList != NULL);
74 }
75
76 /* put map in run time structure (LIBRARY_INTERNAL)
77 * Every map opened or created is
78 * registered in a list for verification
79 * if functions get a valid map handle
80 * passed and for automatic closing
81 * at exit if the application forgets it.
82 */
CsfRegisterMap(MAP * m)83 void CsfRegisterMap(
84 MAP *m) /* map handle to be registered, the field m->mapListId is
85 * initialized
86 */
87 {
88 size_t i=0;
89
90 while (i < mapListLen && mapList[i] != NULL)
91 i++;
92
93 if(i == mapListLen)
94 {
95 size_t j;
96 MAP** mapListNew;
97 /* double size */
98 /* +1 to make clang static analyzer not warn about realloc(0) */
99 mapListLen = 2 * mapListLen + 1;
100 mapListNew=realloc(mapList,sizeof(MAP *)*mapListLen);
101 if (mapListNew == NULL) {
102 (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Not enough memory to use CSF-files\n");
103 exit(1);
104 }
105 mapList = mapListNew;
106 /* initialize new part, i at begin */
107 for(j=i; j < mapListLen; ++j)
108 mapList[j]=0;
109 }
110
111 mapList[i] = m;
112 m->mapListId = (int)i;
113 }
114
115 /* remove map from run time structure (LIBRARY_INTERNAL)
116 * The map handle will become invalid.
117 */
CsfUnloadMap(MAP * m)118 void CsfUnloadMap(
119 MAP *m) /* map handle */
120 {
121 POSTCOND(CsfIsValidMap(m));
122
123 mapList[m->mapListId] = NULL;
124 m->mapListId = -1;
125 }
126
127 /* check if the map handle is created via the csf kernel (LIBRARY_INTERNAL)
128 */
CsfIsValidMap(const MAP * m)129 int CsfIsValidMap(
130 const MAP *m) /* map handle */
131 {
132 return(CsfIsBootedCsfKernel() && m != NULL
133 && m->mapListId >= 0 && ((size_t)m->mapListId) < mapListLen
134 && mapList[m->mapListId] == m);
135 }
136