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