summaryrefslogtreecommitdiff
path: root/inet/inet_ntoa.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
committerUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
commita334319f6530564d22e775935d9c91663623a1b4 (patch)
treeb5877475619e4c938e98757d518bb1e9cbead751 /inet/inet_ntoa.c
parent0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff)
downloadglibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'inet/inet_ntoa.c')
-rw-r--r--inet/inet_ntoa.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/inet/inet_ntoa.c b/inet/inet_ntoa.c
index 38794957c2..889435dd10 100644
--- a/inet/inet_ntoa.c
+++ b/inet/inet_ntoa.c
@@ -21,19 +21,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
+#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 one buffer for
- each thread. */
-static __thread char buffer[18];
+ 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)
{
- unsigned char *bytes = (unsigned char *) &in;
- __snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d",
+ __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);
+}