2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #ifdef __APPLE_PR3375657_HACK__
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.
33 #define PRIVATE __private_extern__
34 //#define SEM_DEBUG_FILE "/tmp/sem_names"
35 //#define SHM_DEBUG_FILE "/tmp/shm_names"
37 #if defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE)
40 #endif /* defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) */
46 #define SEM_PRINTF(fmt, args...) \
49 if (access(SEM_DEBUG_FILE, F_OK) == 0 && \
50 (_sem_fp_ = fopen(SEM_DEBUG_FILE, "a")) != NULL) { \
51 fprintf(_sem_fp_, fmt, ## args); \
55 #endif /* SEM_DEBUG_FILE */
57 #define SHM_PRINTF(fmt, args...) \
60 if (access(SHM_DEBUG_FILE, F_OK) == 0 && \
61 (_shm_fp_ = fopen(SHM_DEBUG_FILE, "a")) != NULL) { \
62 fprintf(_shm_fp_, fmt, ## args); \
66 #endif /* SHM_DEBUG_FILE */
68 /*-----------------------------------------------------------------------
69 * For the Hack structure:
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 *-----------------------------------------------------------------------*/
83 /*-----------------------------------------------------------------------
84 * For the HackList structure:
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
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},
111 static HackList sem_hack_defaults
= {
112 sem_hack_default_names
,
113 (sizeof(sem_hack_default_names
) / sizeof(const Hack
)) - 1,
116 static HackList
*sem_hack_names
= &sem_hack_defaults
;
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},
131 static HackList shm_hack_defaults
= {
132 shm_hack_default_names
,
133 (sizeof(shm_hack_default_names
) / sizeof(const Hack
)) - 1,
136 static HackList
*shm_hack_names
= &shm_hack_defaults
;
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
);
152 /*-----------------------------------------------------------------------
153 * comparkey - used by bsearch to find the Hack structure with the given key
154 *-----------------------------------------------------------------------*/
156 comparkey(const void *key
, const void *h
)
158 return strcmp(key
, ((const Hack
*)h
)->name
);
161 /*-----------------------------------------------------------------------
162 * comparstr - used by qsort to sort the Hack list
163 *-----------------------------------------------------------------------*/
165 comparstr(const void *a
, const void *b
)
167 return strcmp(((const Hack
*)a
)->name
, ((const Hack
*)b
)->name
);
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
177 *-----------------------------------------------------------------------*/
179 dosearch(const char *name
, const HackList
*hl
)
182 int len
= strlen(name
);
187 end
= name
+ len
- 1;
191 while (p
>= name
&& *p
>= '0' && *p
<= '9')
194 if (p
< end
&& (len
= p
- name
) > 0) {
195 key
= alloca(len
+ 1);
198 strncpy(key
, name
, len
);
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
))
208 h
= (const Hack
*)bsearch(name
, hl
->list
, hl
->cur
, sizeof(const Hack
),
210 return (h
&& h
->first
< 0);
213 /*-----------------------------------------------------------------------
214 * hl_add - append to the given HackList a copy of the given Hack structure
215 *-----------------------------------------------------------------------*/
217 hl_add(HackList
*hl
, const Hack
*c
)
225 int s
= hl
->max
+ HACKLISTDELTA
;
226 const Hack
*new = (const Hack
*)realloc((void *)hl
->list
,
227 s
* sizeof(const Hack
));
234 h
= (Hack
*)(hl
->list
+ i
);
235 if ((h
->name
= strdup(c
->name
)) == NULL
)
244 /*-----------------------------------------------------------------------
245 * hl_free - deallocate all memory from the given HackList
246 *-----------------------------------------------------------------------*/
248 hl_free(HackList
*hl
)
253 for (h
= hl
->list
, i
= hl
->cur
; i
> 0; h
++, i
--)
254 free((void *)h
->name
);
255 free((void *)hl
->list
);
259 /*-----------------------------------------------------------------------
260 * hl_init - create a new HackList, with preallocated Hack structures
261 *-----------------------------------------------------------------------*/
265 HackList
*hl
= (HackList
*)malloc(sizeof(HackList
));
269 hl
->list
= (Hack
*)malloc(HACKLISTSTART
* sizeof(Hack
));
275 hl
->max
= HACKLISTSTART
;
279 /*-----------------------------------------------------------------------
280 * initList - initialize a new HackList with the given list of Hack structures
281 *-----------------------------------------------------------------------*/
283 initList(const Hack
*list
)
285 HackList
*hl
= hl_init();
289 for (; list
->name
; list
++)
290 if (hl_add(hl
, list
) < 0) {
297 /*-----------------------------------------------------------------------
298 * PUBLIC _sem_hack_add - add the given Hack list to sem_hack_names.
299 *-----------------------------------------------------------------------*/
301 _sem_hack_add(const Hack
*list
)
305 if (sem_hack_names
== &sem_hack_defaults
) {
306 HackList
*hl
= initList(sem_hack_default_names
);
311 for (; list
->name
; list
++)
312 if (hl_add(sem_hack_names
, list
) < 0)
314 qsort((void *)sem_hack_names
->list
, sem_hack_names
->cur
,
315 sizeof(const Hack
), comparstr
);
319 /*-----------------------------------------------------------------------
320 * PUBLIC _sem_hack_init - reinitialize sem_hack_names to the default
321 *-----------------------------------------------------------------------*/
325 if (sem_hack_names
== &sem_hack_defaults
)
327 hl_free(sem_hack_names
);
328 sem_hack_names
= &sem_hack_defaults
;
331 /*-----------------------------------------------------------------------
332 * _sem_match - try to match the given named to sem_hack_names. Called
333 * by sem_open() and sem_unlink().
334 *-----------------------------------------------------------------------*/
336 _sem_match(const char *name
)
338 #ifdef SEM_DEBUG_FILE
340 #endif /* SEM_DEBUG_FILE */
344 #ifdef SEM_DEBUG_FILE
345 match
= dosearch(name
, sem_hack_names
);
347 SEM_PRINTF("%s\n", name
);
349 #else /* SEM_DEBUG_FILE */
350 return dosearch(name
, sem_hack_names
);
351 #endif /* SEM_DEBUG_FILE */
354 /*-----------------------------------------------------------------------
355 * PUBLIC _shm_hack_add - add the given Hack list to shm_hack_names.
356 *-----------------------------------------------------------------------*/
358 _shm_hack_add(const Hack
*list
)
362 if (shm_hack_names
== &shm_hack_defaults
) {
363 HackList
*hl
= initList(shm_hack_default_names
);
368 for (; list
->name
; list
++)
369 if (hl_add(shm_hack_names
, list
) < 0)
371 qsort((void *)shm_hack_names
->list
, shm_hack_names
->cur
,
372 sizeof(const Hack
), comparstr
);
376 /*-----------------------------------------------------------------------
377 * PUBLIC _shm_hack_init - reinitialize shm_hack_names to the default
378 *-----------------------------------------------------------------------*/
382 if (shm_hack_names
== &shm_hack_defaults
)
384 hl_free(shm_hack_names
);
385 shm_hack_names
= &shm_hack_defaults
;
388 /*-----------------------------------------------------------------------
389 * _shm_match - try to match the given named to shm_hack_names. Called
390 * by shm_open() and shm_unlink().
391 *-----------------------------------------------------------------------*/
393 _shm_match(const char *name
)
395 #ifdef SHM_DEBUG_FILE
397 #endif /* SHM_DEBUG_FILE */
401 #ifdef SHM_DEBUG_FILE
402 match
= dosearch(name
, shm_hack_names
);
404 SHM_PRINTF("%s\n", name
);
406 #else /* SHM_DEBUG_FILE */
407 return dosearch(name
, shm_hack_names
);
408 #endif /* SHM_DEBUG_FILE */
411 #endif /* __APPLE_PR3375657_HACK__ */