glibc 2.3 pthread patch

Ove Kaaven ovehk at ping.uio.no
Sun Oct 20 15:54:18 CDT 2002


Now that glibc 2.3 is available for those bleeding-edge folks on debian
unstable, it seems that Wines compiled on 2.2 won't run on 2.3 systems.
The glibc folks did warn us about this a while ago though, so here's a
patch that implements their suggestion for making wine compatible with as
many glibc versions as possible. Perhaps Alexandre wants to use his
WINE_GET_SONAME stuff to detect the name of the libc at configure time
instead of at runtime like I do, though.

Log:
Ove Kaaven <ovek at transgaming.com>
Resolve libc symbols we need (fork and sigaction) at runtime with dlsym()
so that Wine runs on newer glibc versions than what it was compiled on.

Index: scheduler/pthread.c
===================================================================
RCS file: /cvsroot/winex/wine/scheduler/pthread.c,v
retrieving revision 1.11
diff -u -r1.11 pthread.c
--- scheduler/pthread.c	25 Sep 2002 20:15:50 -0000	1.11
+++ scheduler/pthread.c	20 Oct 2002 20:28:36 -0000
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <dlfcn.h>
 
 #include "winbase.h"
 #include "thread.h"
@@ -64,21 +65,11 @@
      "\tjmp " PSTR(orig))
 #endif
 
-/* get necessary libc symbols */
-#if (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1) && defined(HAVE___LIBC_FORK)
-#define LIBC_FORK __libc_fork
-#define PTHREAD_FORK __fork
-#define ALIAS_FORK
-#else
-#define LIBC_FORK __fork
-#define PTHREAD_FORK fork
-#endif
-extern pid_t LIBC_FORK(void);
-
-#define LIBC_SIGACTION __sigaction
-extern int LIBC_SIGACTION(int signum,
-                         const struct sigaction *act,
-                         struct sigaction *oldact);
+static void *libc_handle = NULL;
+static pid_t (*libc_fork)(void);
+static int (*libc_sigaction)(int signum,
+                             const struct sigaction *act,
+                             struct sigaction *oldact);
 
 /* NOTE: This is a truly extremely incredibly ugly hack!
  * But it does seem to work... */
@@ -113,6 +104,25 @@
 #define P_OUTPUT(stuff) write(2,stuff,strlen(stuff))
 #endif
 
+static void grab_libc(void)
+{
+  void *libc_open;
+  Dl_info info;
+
+  if (libc_handle) return;
+
+  /* to find the real name of libc, we can either detect it with configure
+   * and compile the name into wine, or detect it at runtime, like this */
+  libc_open = dlsym(RTLD_NEXT, "fopen");
+  dladdr(libc_open, &info); /* <== GNU extension */
+
+  /* now we can grab a libc handle */
+  libc_handle = dlopen(info.dli_fname, RTLD_LAZY);
+  /* and thus the entry points we need */
+  libc_fork = dlsym(libc_handle, "fork");
+  libc_sigaction = dlsym(libc_handle, "sigaction");
+}
+
 void __pthread_initialize(void)
 {
 }
@@ -254,15 +264,16 @@
 }
 strong_alias(__pthread_atfork, pthread_atfork);
 
-pid_t PTHREAD_FORK(void)
+pid_t __fork(void)
 {
     pid_t pid;
     int i;
 
     EnterCriticalSection( &atfork_section );
+    grab_libc();
     /* prepare handlers are called in reverse insertion order */
     for (i = atfork_count - 1; i >= 0; i--) if (atfork_prepare[i]) atfork_prepare[i]();
-    if (!(pid = LIBC_FORK()))
+    if (!(pid = (*libc_fork)()))
     {
         InitializeCriticalSection( &atfork_section );
         for (i = 0; i < atfork_count; i++) if (atfork_child[i]) atfork_child[i]();
@@ -274,9 +285,7 @@
     }
     return pid;
 }
-#ifdef ALIAS_FORK
-strong_alias(PTHREAD_FORK, fork);
-#endif
+strong_alias(__fork, fork);
 
 /***** MUTEXES *****/
 
@@ -657,14 +666,11 @@
 /***** ANTI-OVERRIDES *****/
 /* pthreads tries to override these, point them back to libc */
 
-#ifdef jump_alias
-jump_alias(LIBC_SIGACTION, sigaction);
-#else
 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
 {
-  return LIBC_SIGACTION(signum, act, oldact);
+  grab_libc();
+  return (*libc_sigaction)(signum, act, oldact);
 }
-#endif
 
 #endif /* __GLIBC__ */
 




More information about the wine-patches mailing list