]> git.saurik.com Git - apple/libc.git/blob - sys/fix-3375657.c
Libc-498.1.7.tar.gz
[apple/libc.git] / sys / fix-3375657.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * When mutexes or spinlocks were added for thread safety, the system would
26 * hang during the boot process, just after changing to the blue background.
27 * So for the common case of not calling _s[eh]m_hack_{add,init}(), we just
28 * use static name lists. This should be reinvestigated when there is time.
29 */
30
31 #define PRIVATE __private_extern__
32 //#define SEM_DEBUG_FILE "/tmp/sem_names"
33 //#define SHM_DEBUG_FILE "/tmp/shm_names"
34
35 #if defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE)
36 #include <stdio.h>
37 #include <unistd.h>
38 #endif /* defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) */
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdlib.h>
42
43 #ifdef SEM_DEBUG_FILE
44 #define SEM_PRINTF(fmt, args...) \
45 { \
46 FILE *_sem_fp_; \
47 if (access(SEM_DEBUG_FILE, F_OK) == 0 && \
48 (_sem_fp_ = fopen(SEM_DEBUG_FILE, "a")) != NULL) { \
49 fprintf(_sem_fp_, fmt, ## args); \
50 fclose(_sem_fp_); \
51 } \
52 }
53 #endif /* SEM_DEBUG_FILE */
54 #ifdef SHM_DEBUG_FILE
55 #define SHM_PRINTF(fmt, args...) \
56 { \
57 FILE *_shm_fp_; \
58 if (access(SHM_DEBUG_FILE, F_OK) == 0 && \
59 (_shm_fp_ = fopen(SHM_DEBUG_FILE, "a")) != NULL) { \
60 fprintf(_shm_fp_, fmt, ## args); \
61 fclose(_shm_fp_); \
62 } \
63 }
64 #endif /* SHM_DEBUG_FILE */
65
66 /*-----------------------------------------------------------------------
67 * For the Hack structure:
68 *
69 * first >= 0 starting serial number
70 * first < 0 no serial number
71 * last ending serial number (only if first >= 0)
72 * debug whether an option 'D' can be appended
73 *-----------------------------------------------------------------------*/
74 typedef struct {
75 const char *name;
76 int first;
77 int last;
78 int debug;
79 } Hack;
80
81 /*-----------------------------------------------------------------------
82 * For the HackList structure:
83 *
84 * list the list of Hack structures
85 * cur the number of valid Hack structures in list
86 * max the actual number of Hack structures allocated
87 *-----------------------------------------------------------------------*/
88 #define HACKLISTDELTA 16
89 #define HACKLISTSTART 16
90 typedef struct {
91 const Hack *list;
92 int cur;
93 int max;
94 } HackList;
95
96 static const Hack sem_hack_default_names[] = {
97 {"EDBPool", 1, 255, 0},
98 {"EDDPoolLock", -1, 0, 0},
99 {"Mso97SharedDg", 1920, 2047, 1},
100 {"Office", 1920, 2047, 1},
101 {"PT_EDBPool", 1, 255, 0},
102 {"PT_EDDPoolLock", -1, 0, 0},
103 {"PT_Mso97SharedDg", 1920, 2047, 0},
104 {"PT_Office", 1920, 2047, 0},
105 {"ShMemExtCritSection", -1, 0, 0},
106 {"ShMemIntCritSection", -1, 0, 0},
107 {NULL, 0, 0, 0},
108 };
109 static HackList sem_hack_defaults = {
110 sem_hack_default_names,
111 (sizeof(sem_hack_default_names) / sizeof(const Hack)) - 1,
112 0
113 };
114 static HackList *sem_hack_names = &sem_hack_defaults;
115
116 static const Hack shm_hack_default_names[] = {
117 {"EDBPool", 1, 255, 0},
118 {"EDDPoolLock", -1, 0, 0},
119 {"Mso97SharedDg", 1920, 2047, 1},
120 {"Office", 1920, 2047, 1},
121 {"PT_EDBPool", 1, 255, 0},
122 {"PT_EDDPoolLock", -1, 0, 0},
123 {"PT_Mso97SharedDg", 1920, 2047, 0},
124 {"PT_Office", 1920, 2047, 0},
125 {"PT_ShMemRefCount", -1, 0, 0}, /* not specified by MS, but seen */
126 {"ShMemRefCount", -1, 0, 0},
127 {NULL, 0, 0, 0},
128 };
129 static HackList shm_hack_defaults = {
130 shm_hack_default_names,
131 (sizeof(shm_hack_default_names) / sizeof(const Hack)) - 1,
132 0
133 };
134 static HackList *shm_hack_names = &shm_hack_defaults;
135
136 static int comparkey(const void *key, const void *hname);
137 static int comparstr(const void *a, const void *b);
138 static int dosearch(const char *name, const HackList *hl);
139 static int hl_add(HackList *hl, const Hack *h);
140 static void hl_free(HackList *hl);
141 static HackList *hl_init(void);
142 static HackList *initList(const Hack *list);
143 int _sem_hack_add(const Hack *list);
144 void _sem_hack_init(void);
145 PRIVATE int _sem_match(const char *name);
146 int _shm_hack_add(const Hack *list);
147 void _shm_hack_init(void);
148 PRIVATE int _shm_match(const char *name);
149
150 /*-----------------------------------------------------------------------
151 * comparkey - used by bsearch to find the Hack structure with the given key
152 *-----------------------------------------------------------------------*/
153 static int
154 comparkey(const void *key, const void *h)
155 {
156 return strcmp(key, ((const Hack *)h)->name);
157 }
158
159 /*-----------------------------------------------------------------------
160 * comparstr - used by qsort to sort the Hack list
161 *-----------------------------------------------------------------------*/
162 static int
163 comparstr(const void *a, const void *b)
164 {
165 return strcmp(((const Hack *)a)->name, ((const Hack *)b)->name);
166 }
167
168 /*-----------------------------------------------------------------------
169 * dosearch - search of the given name in the given HackList. First see
170 * if there is a trailing D, and a serial number. If the serial number
171 * exists, try to match without the serial number, checking the series
172 * range and whether the trailing D is allowed. Otherwise, try to match
173 * the whole string, but check if the matched Hack structure requires a
174 * serial number.
175 *-----------------------------------------------------------------------*/
176 static int
177 dosearch(const char *name, const HackList *hl)
178 {
179 int series;
180 int len = strlen(name);
181 const char *end, *p;
182 char *key;
183 const Hack *h;
184
185 end = name + len - 1;
186 if (*end != 'D')
187 end++;
188 p = end - 1;
189 while (p >= name && *p >= '0' && *p <= '9')
190 p--;
191 p++;
192 if (p < end && (len = p - name) > 0) {
193 key = alloca(len + 1);
194 if (key) {
195 series = atoi(p);
196 strncpy(key, name, len);
197 key[len] = 0;
198 h = (const Hack *)bsearch(key, hl->list, hl->cur,
199 sizeof(const Hack), comparkey);
200 if (h && h->first >= 0
201 && series >= h->first && series <= h->last
202 && (*end == 0 || h->debug))
203 return 1;
204 }
205 }
206 h = (const Hack *)bsearch(name, hl->list, hl->cur, sizeof(const Hack),
207 comparkey);
208 return (h && h->first < 0);
209 }
210
211 /*-----------------------------------------------------------------------
212 * hl_add - append to the given HackList a copy of the given Hack structure
213 *-----------------------------------------------------------------------*/
214 static int
215 hl_add(HackList *hl, const Hack *c)
216 {
217 int i = hl->cur;
218 Hack *h;
219
220 if (!c->name)
221 return -1;
222 if (i >= hl->max) {
223 int s = hl->max + HACKLISTDELTA;
224 const Hack *new = (const Hack *)realloc((void *)hl->list,
225 s * sizeof(const Hack));
226
227 if (!new)
228 return -1;
229 hl->list = new;
230 hl->max = s;
231 }
232 h = (Hack *)(hl->list + i);
233 if ((h->name = strdup(c->name)) == NULL)
234 return -1;
235 h->first = c->first;
236 h->last = c->last;
237 h->debug = c->debug;
238 hl->cur++;
239 return 0;
240 }
241
242 /*-----------------------------------------------------------------------
243 * hl_free - deallocate all memory from the given HackList
244 *-----------------------------------------------------------------------*/
245 static void
246 hl_free(HackList *hl)
247 {
248 const Hack *h;
249 int i;
250
251 for (h = hl->list, i = hl->cur; i > 0; h++, i--)
252 free((void *)h->name);
253 free((void *)hl->list);
254 free(hl);
255 }
256
257 /*-----------------------------------------------------------------------
258 * hl_init - create a new HackList, with preallocated Hack structures
259 *-----------------------------------------------------------------------*/
260 static HackList *
261 hl_init(void)
262 {
263 HackList *hl = (HackList *)malloc(sizeof(HackList));
264
265 if (!hl)
266 return NULL;
267 hl->list = (Hack *)malloc(HACKLISTSTART * sizeof(Hack));
268 if (!hl->list) {
269 free(hl);
270 return NULL;
271 }
272 hl->cur = 0;
273 hl->max = HACKLISTSTART;
274 return hl;
275 }
276
277 /*-----------------------------------------------------------------------
278 * initList - initialize a new HackList with the given list of Hack structures
279 *-----------------------------------------------------------------------*/
280 static HackList *
281 initList(const Hack *list)
282 {
283 HackList *hl = hl_init();
284
285 if (hl == NULL)
286 return NULL;
287 for (; list->name; list++)
288 if (hl_add(hl, list) < 0) {
289 hl_free(hl);
290 return NULL;
291 }
292 return hl;
293 }
294
295 /*-----------------------------------------------------------------------
296 * PUBLIC _sem_hack_add - add the given Hack list to sem_hack_names.
297 *-----------------------------------------------------------------------*/
298 int
299 _sem_hack_add(const Hack *list)
300 {
301 if (list == NULL)
302 return -1;
303 if (sem_hack_names == &sem_hack_defaults) {
304 HackList *hl = initList(sem_hack_default_names);
305 if (!hl)
306 return -1;
307 sem_hack_names = hl;
308 }
309 for (; list->name; list++)
310 if (hl_add(sem_hack_names, list) < 0)
311 return -1;
312 qsort((void *)sem_hack_names->list, sem_hack_names->cur,
313 sizeof(const Hack), comparstr);
314 return 0;
315 }
316
317 /*-----------------------------------------------------------------------
318 * PUBLIC _sem_hack_init - reinitialize sem_hack_names to the default
319 *-----------------------------------------------------------------------*/
320 void
321 _sem_hack_init(void)
322 {
323 if (sem_hack_names == &sem_hack_defaults)
324 return;
325 hl_free(sem_hack_names);
326 sem_hack_names = &sem_hack_defaults;
327 }
328
329 /*-----------------------------------------------------------------------
330 * _sem_match - try to match the given named to sem_hack_names. Called
331 * by sem_open() and sem_unlink().
332 *-----------------------------------------------------------------------*/
333 PRIVATE int
334 _sem_match(const char *name)
335 {
336 #ifdef SEM_DEBUG_FILE
337 int match;
338 #endif /* SEM_DEBUG_FILE */
339
340 if (!name || !*name)
341 return 0;
342 #ifdef SEM_DEBUG_FILE
343 match = dosearch(name, sem_hack_names);
344 if (!match)
345 SEM_PRINTF("%s\n", name);
346 return match;
347 #else /* SEM_DEBUG_FILE */
348 return dosearch(name, sem_hack_names);
349 #endif /* SEM_DEBUG_FILE */
350 }
351
352 /*-----------------------------------------------------------------------
353 * PUBLIC _shm_hack_add - add the given Hack list to shm_hack_names.
354 *-----------------------------------------------------------------------*/
355 int
356 _shm_hack_add(const Hack *list)
357 {
358 if (list == NULL)
359 return -1;
360 if (shm_hack_names == &shm_hack_defaults) {
361 HackList *hl = initList(shm_hack_default_names);
362 if (!hl)
363 return -1;
364 shm_hack_names = hl;
365 }
366 for (; list->name; list++)
367 if (hl_add(shm_hack_names, list) < 0)
368 return -1;
369 qsort((void *)shm_hack_names->list, shm_hack_names->cur,
370 sizeof(const Hack), comparstr);
371 return 0;
372 }
373
374 /*-----------------------------------------------------------------------
375 * PUBLIC _shm_hack_init - reinitialize shm_hack_names to the default
376 *-----------------------------------------------------------------------*/
377 void
378 _shm_hack_init(void)
379 {
380 if (shm_hack_names == &shm_hack_defaults)
381 return;
382 hl_free(shm_hack_names);
383 shm_hack_names = &shm_hack_defaults;
384 }
385
386 /*-----------------------------------------------------------------------
387 * _shm_match - try to match the given named to shm_hack_names. Called
388 * by shm_open() and shm_unlink().
389 *-----------------------------------------------------------------------*/
390 PRIVATE int
391 _shm_match(const char *name)
392 {
393 #ifdef SHM_DEBUG_FILE
394 int match;
395 #endif /* SHM_DEBUG_FILE */
396
397 if (!name || !*name)
398 return 0;
399 #ifdef SHM_DEBUG_FILE
400 match = dosearch(name, shm_hack_names);
401 if (!match)
402 SHM_PRINTF("%s\n", name);
403 return match;
404 #else /* SHM_DEBUG_FILE */
405 return dosearch(name, shm_hack_names);
406 #endif /* SHM_DEBUG_FILE */
407 }