This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: inet_ntoa.c without TLS


The recent change to inet_ntoa.c will fail on systems without TLS support.  
Please consider the attached patch, which re-implements the original TLD code 
when TLS is not available.

2006-05-25  Kristian Van Der Vliet  <vanders@liqwyd.com>

	* inet/inet_ntoa.c: Provide a TLD version for systems that lack TLS.

-- 
Vanders
http://www.syllable.org
http://www.liqwyd.com
Index: inet_ntoa.c
===================================================================
RCS file: /cvs/glibc/libc/inet/inet_ntoa.c,v
retrieving revision 1.13
diff -u -p -r1.13 inet_ntoa.c
--- inet_ntoa.c	9 Apr 2006 05:50:08 -0000	1.13
+++ inet_ntoa.c	25 May 2006 15:29:59 -0000
@@ -21,6 +21,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <arpa/inet.h>
+#include <tls.h>
+
+#if USE___THREAD
 
 /* The interface of this function is completely stupid, it requires a
    static buffer.  We relax this a bit in that we allow one buffer for
@@ -37,3 +40,92 @@ inet_ntoa (struct in_addr in)
 
   return buffer;
 }
+
+#else
+
+#include <bits/libc-lock.h>
+
+/* The interface of this function is completely stupid, it requires a
+   static buffer.  We relax this a bit in that we allow at least one
+   buffer for each thread.  */
+
+/* This is the key for the thread specific memory.  */
+static __libc_key_t key;
+
+/* If nonzero the key allocation failed and we should better use a
+   static buffer than fail.  */
+static char local_buf[18];
+static char *static_buf;
+
+/* Destructor for the thread-specific data.  */
+static void init (void);
+static void free_key_mem (void *mem);
+
+
+char *
+inet_ntoa (struct in_addr in)
+{
+  __libc_once_define (static, once);
+  char *buffer;
+  unsigned char *bytes;
+
+  /* If we have not yet initialized the buffer do it now.  */
+  __libc_once (once, init);
+
+  if (static_buf != NULL)
+    buffer = static_buf;
+  else
+    {
+      /* We don't use the static buffer and so we have a key.  Use it
+	 to get the thread-specific buffer.  */
+      buffer = __libc_getspecific (key);
+      if (buffer == NULL)
+	{
+	  /* No buffer allocated so far.  */
+	  buffer = malloc (18);
+	  if (buffer == NULL)
+	    /* No more memory available.  We use the static buffer.  */
+	    buffer = local_buf;
+	  else
+	    __libc_setspecific (key, buffer);
+	}
+    }
+
+  bytes = (unsigned char *) &in;
+  __snprintf (buffer, 18, "%d.%d.%d.%d",
+	      bytes[0], bytes[1], bytes[2], bytes[3]);
+
+  return buffer;
+}
+
+
+/* Initialize buffer.  */
+static void
+init (void)
+{
+  if (__libc_key_create (&key, free_key_mem))
+    /* Creating the key failed.  This means something really went
+       wrong.  In any case use a static buffer which is better than
+       nothing.  */
+    static_buf = local_buf;
+}
+
+
+/* Free the thread specific data, this is done if a thread terminates.  */
+static void
+free_key_mem (void *mem)
+{
+  free (mem);
+  __libc_setspecific (key, NULL);
+}
+
+
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  free (static_buf);
+}
+text_set_element (__libc_subfreeres, free_mem);
+
+#endif
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]