]> git.saurik.com Git - apple/libc.git/blobdiff - sys/fix-3375657.c
Libc-320.tar.gz
[apple/libc.git] / sys / fix-3375657.c
diff --git a/sys/fix-3375657.c b/sys/fix-3375657.c
new file mode 100644 (file)
index 0000000..e60c9bb
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifdef __APPLE_PR3375657_HACK__
+
+/*
+ * When mutexes or spinlocks were added for thread safety, the system would
+ * hang during the boot process, just after changing to the blue background.
+ * So for the common case of not calling _s[eh]m_hack_{add,init}(), we just
+ * use static name lists.  This should be reinvestigated when there is time.
+ */
+
+#define PRIVATE                __private_extern__
+//#define SEM_DEBUG_FILE       "/tmp/sem_names"
+//#define SHM_DEBUG_FILE       "/tmp/shm_names"
+
+#if defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE)
+#include <stdio.h>
+#include <unistd.h>
+#endif /* defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) */
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef SEM_DEBUG_FILE
+#define SEM_PRINTF(fmt, args...) \
+{ \
+       FILE *_sem_fp_; \
+       if (access(SEM_DEBUG_FILE, F_OK) == 0 && \
+           (_sem_fp_ = fopen(SEM_DEBUG_FILE, "a")) != NULL) { \
+               fprintf(_sem_fp_, fmt, ## args); \
+               fclose(_sem_fp_); \
+       } \
+}
+#endif /* SEM_DEBUG_FILE */
+#ifdef SHM_DEBUG_FILE
+#define SHM_PRINTF(fmt, args...) \
+{ \
+       FILE *_shm_fp_; \
+       if (access(SHM_DEBUG_FILE, F_OK) == 0 && \
+           (_shm_fp_ = fopen(SHM_DEBUG_FILE, "a")) != NULL) { \
+               fprintf(_shm_fp_, fmt, ## args); \
+               fclose(_shm_fp_); \
+       } \
+}
+#endif /* SHM_DEBUG_FILE */
+
+/*-----------------------------------------------------------------------
+ * For the Hack structure:
+ *
+ * first >= 0  starting serial number
+ * first < 0   no serial number
+ * last                ending serial number (only if first >= 0)
+ * debug       whether an option 'D' can be appended
+ *-----------------------------------------------------------------------*/
+typedef struct {
+       const char *name;
+       int first;
+       int last;
+       int debug;
+} Hack;
+
+/*-----------------------------------------------------------------------
+ * For the HackList structure:
+ *
+ * list                the list of Hack structures
+ * cur         the number of valid Hack structures in list
+ * max         the actual number of Hack structures allocated
+ *-----------------------------------------------------------------------*/
+#define        HACKLISTDELTA   16
+#define        HACKLISTSTART   16
+typedef struct {
+       const Hack *list;
+       int cur;
+       int max;
+} HackList;
+
+static const Hack sem_hack_default_names[] = {
+       {"EDBPool", 1, 255, 0},
+       {"EDDPoolLock", -1, 0, 0},
+       {"Mso97SharedDg", 1920, 2047, 1},
+       {"Office", 1920, 2047, 1},
+       {"PT_EDBPool", 1, 255, 0},
+       {"PT_EDDPoolLock", -1, 0, 0},
+       {"PT_Mso97SharedDg", 1920, 2047, 0},
+       {"PT_Office", 1920, 2047, 0},
+       {"ShMemExtCritSection", -1, 0, 0},
+       {"ShMemIntCritSection", -1, 0, 0},
+       {NULL, 0, 0, 0},
+};
+static HackList sem_hack_defaults = {
+       sem_hack_default_names,
+       (sizeof(sem_hack_default_names) / sizeof(const Hack)) - 1,
+       0
+};
+static HackList *sem_hack_names = &sem_hack_defaults;
+
+static const Hack shm_hack_default_names[] = {
+       {"EDBPool", 1, 255, 0},
+       {"EDDPoolLock", -1, 0, 0},
+       {"Mso97SharedDg", 1920, 2047, 1},
+       {"Office", 1920, 2047, 1},
+       {"PT_EDBPool", 1, 255, 0},
+       {"PT_EDDPoolLock", -1, 0, 0},
+       {"PT_Mso97SharedDg", 1920, 2047, 0},
+       {"PT_Office", 1920, 2047, 0},
+       {"PT_ShMemRefCount", -1, 0, 0}, /* not specified by MS, but seen */
+       {"ShMemRefCount", -1, 0, 0},
+       {NULL, 0, 0, 0},
+};
+static HackList shm_hack_defaults = {
+       shm_hack_default_names,
+       (sizeof(shm_hack_default_names) / sizeof(const Hack)) - 1,
+       0
+};
+static HackList *shm_hack_names = &shm_hack_defaults;
+
+static int comparkey(const void *key, const void *hname);
+static int comparstr(const void *a, const void *b);
+static int dosearch(const char *name, const HackList *hl);
+static int hl_add(HackList *hl, const Hack *h);
+static void hl_free(HackList *hl);
+static HackList *hl_init(void);
+static HackList *initList(const Hack *list);
+int _sem_hack_add(const Hack *list);
+void _sem_hack_init(void);
+PRIVATE int _sem_match(const char *name);
+int _shm_hack_add(const Hack *list);
+void _shm_hack_init(void);
+PRIVATE int _shm_match(const char *name);
+
+/*-----------------------------------------------------------------------
+ * comparkey - used by bsearch to find the Hack structure with the given key
+ *-----------------------------------------------------------------------*/
+static int
+comparkey(const void *key, const void *h)
+{
+       return strcmp(key, ((const Hack *)h)->name);
+}
+
+/*-----------------------------------------------------------------------
+ * comparstr - used by qsort to sort the Hack list
+ *-----------------------------------------------------------------------*/
+static int
+comparstr(const void *a, const void *b)
+{
+       return strcmp(((const Hack *)a)->name, ((const Hack *)b)->name);
+}
+
+/*-----------------------------------------------------------------------
+ * dosearch - search of the given name in the given HackList.  First see
+ * if there is a trailing D, and a serial number.  If the serial number
+ * exists, try to match without the serial number, checking the series
+ * range and whether the trailing D is allowed.  Otherwise, try to match
+ * the whole string, but check if the matched Hack structure requires a
+ * serial number.
+ *-----------------------------------------------------------------------*/
+static int
+dosearch(const char *name, const HackList *hl)
+{
+       int series;
+       int len = strlen(name);
+       const char *end, *p;
+       char *key;
+       const Hack *h;
+
+       end = name + len - 1;
+       if (*end != 'D')
+               end++;
+       p = end - 1;
+       while (p >= name && *p >= '0' && *p <= '9')
+               p--;
+       p++;
+       if (p < end && (len = p - name) > 0) {
+               key = alloca(len + 1);
+               if (key) {
+                       series = atoi(p);
+                       strncpy(key, name, len);
+                       key[len] = 0;
+                       h = (const Hack *)bsearch(key, hl->list, hl->cur,
+                           sizeof(const Hack), comparkey);
+                       if (h && h->first >= 0
+                           && series >= h->first && series <= h->last
+                           && (*end == 0 || h->debug))
+                               return 1;
+               }
+       }
+       h = (const Hack *)bsearch(name, hl->list, hl->cur, sizeof(const Hack),
+           comparkey);
+       return (h && h->first < 0);
+}
+
+/*-----------------------------------------------------------------------
+ * hl_add - append to the given HackList a copy of the given Hack structure
+ *-----------------------------------------------------------------------*/
+static int
+hl_add(HackList *hl, const Hack *c)
+{
+       int i = hl->cur;
+       Hack *h;
+
+       if (!c->name)
+               return -1;
+       if (i >= hl->max) {
+               int s = hl->max + HACKLISTDELTA;
+               const Hack *new = (const Hack *)realloc((void *)hl->list,
+                   s * sizeof(const Hack));
+
+               if (!new)
+                       return -1;
+               hl->list = new;
+               hl->max = s;
+       }
+       h = (Hack *)(hl->list + i);
+       if ((h->name = strdup(c->name)) == NULL)
+               return -1;
+       h->first = c->first;
+       h->last = c->last;
+       h->debug = c->debug;
+       hl->cur++;
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * hl_free - deallocate all memory from the given HackList
+ *-----------------------------------------------------------------------*/
+static void
+hl_free(HackList *hl)
+{
+       const Hack *h;
+       int i;
+
+       for (h = hl->list, i = hl->cur; i > 0; h++, i--)
+               free((void *)h->name);
+       free((void *)hl->list);
+       free(hl);
+}
+
+/*-----------------------------------------------------------------------
+ * hl_init - create a new HackList, with preallocated Hack structures
+ *-----------------------------------------------------------------------*/
+static HackList *
+hl_init(void)
+{
+       HackList *hl = (HackList *)malloc(sizeof(HackList));
+
+       if (!hl)
+               return NULL;
+       hl->list = (Hack *)malloc(HACKLISTSTART * sizeof(Hack));
+       if (!hl->list) {
+               free(hl);
+               return NULL;
+       }
+       hl->cur = 0;
+       hl->max = HACKLISTSTART;
+       return hl;
+}
+
+/*-----------------------------------------------------------------------
+ * initList - initialize a new HackList with the given list of Hack structures
+ *-----------------------------------------------------------------------*/
+static HackList *
+initList(const Hack *list)
+{
+       HackList *hl = hl_init();
+
+       if (hl == NULL)
+               return NULL;
+       for (; list->name; list++)
+               if (hl_add(hl, list) < 0) {
+                       hl_free(hl);
+                       return NULL;
+               }
+       return hl;
+}
+
+/*-----------------------------------------------------------------------
+ * PUBLIC _sem_hack_add - add the given Hack list to sem_hack_names.
+ *-----------------------------------------------------------------------*/
+int
+_sem_hack_add(const Hack *list)
+{
+       if (list == NULL)
+               return -1;
+       if (sem_hack_names == &sem_hack_defaults) {
+               HackList *hl = initList(sem_hack_default_names);
+               if (!hl)
+                       return -1;
+               sem_hack_names = hl;
+       }
+       for (; list->name; list++)
+               if (hl_add(sem_hack_names, list) < 0)
+                       return -1;
+       qsort((void *)sem_hack_names->list, sem_hack_names->cur,
+           sizeof(const Hack), comparstr);
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * PUBLIC _sem_hack_init - reinitialize sem_hack_names to the default
+ *-----------------------------------------------------------------------*/
+void
+_sem_hack_init(void)
+{
+       if (sem_hack_names == &sem_hack_defaults)
+               return;
+       hl_free(sem_hack_names);
+       sem_hack_names = &sem_hack_defaults;
+}
+
+/*-----------------------------------------------------------------------
+ * _sem_match - try to match the given named to sem_hack_names.  Called
+ * by sem_open() and sem_unlink().
+ *-----------------------------------------------------------------------*/
+PRIVATE int
+_sem_match(const char *name)
+{
+#ifdef SEM_DEBUG_FILE
+       int match;
+#endif /* SEM_DEBUG_FILE */
+
+       if (!name || !*name)
+               return 0;
+#ifdef SEM_DEBUG_FILE
+       match = dosearch(name, sem_hack_names);
+       if (!match)
+               SEM_PRINTF("%s\n", name);
+       return match;
+#else /* SEM_DEBUG_FILE */
+       return dosearch(name, sem_hack_names);
+#endif /* SEM_DEBUG_FILE */
+}
+
+/*-----------------------------------------------------------------------
+ * PUBLIC _shm_hack_add - add the given Hack list to shm_hack_names.
+ *-----------------------------------------------------------------------*/
+int
+_shm_hack_add(const Hack *list)
+{
+       if (list == NULL)
+               return -1;
+       if (shm_hack_names == &shm_hack_defaults) {
+               HackList *hl = initList(shm_hack_default_names);
+               if (!hl)
+                       return -1;
+               shm_hack_names = hl;
+       }
+       for (; list->name; list++)
+               if (hl_add(shm_hack_names, list) < 0)
+                       return -1;
+       qsort((void *)shm_hack_names->list, shm_hack_names->cur,
+           sizeof(const Hack), comparstr);
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * PUBLIC _shm_hack_init - reinitialize shm_hack_names to the default
+ *-----------------------------------------------------------------------*/
+void
+_shm_hack_init(void)
+{
+       if (shm_hack_names == &shm_hack_defaults)
+               return;
+       hl_free(shm_hack_names);
+       shm_hack_names = &shm_hack_defaults;
+}
+
+/*-----------------------------------------------------------------------
+ * _shm_match - try to match the given named to shm_hack_names.  Called
+ * by shm_open() and shm_unlink().
+ *-----------------------------------------------------------------------*/
+PRIVATE int
+_shm_match(const char *name)
+{
+#ifdef SHM_DEBUG_FILE
+       int match;
+#endif /* SHM_DEBUG_FILE */
+
+       if (!name || !*name)
+               return 0;
+#ifdef SHM_DEBUG_FILE
+       match = dosearch(name, shm_hack_names);
+       if (!match)
+               SHM_PRINTF("%s\n", name);
+       return match;
+#else /* SHM_DEBUG_FILE */
+       return dosearch(name, shm_hack_names);
+#endif /* SHM_DEBUG_FILE */
+}
+
+#endif /* __APPLE_PR3375657_HACK__ */