diff --git a/configure.in b/configure.in
index f085d365ed28a284dc053dabc3786746901b6573..8ce3a9aea670679edffac5cf0abd067e99848bb9 100644
--- a/configure.in
+++ b/configure.in
@@ -733,7 +733,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
  strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
  sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
  unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
- sys/ioctl.h)
+ sys/ioctl.h malloc.h sys/malloc.h)
 
 #--------------------------------------------------------------------
 # Check for system libraries. Adds the library to $LIBS
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 4247b951d82a4f716e5f97e576e28bbecabc8f8b..16a14ac503863fb873a22e3fea607ea750bb69df 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -637,6 +637,7 @@ struct st_my_thread_var
   long id;
   int cmp_length;
   int volatile abort;
+  my_bool init;
 #ifndef DBUG_OFF
   gptr dbug;
   char name[THREAD_NAME_SIZE+1];
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 52ff08b878706e41273a438b1e49b43523707371..d33f384f81e425b3324c7709456d2953313e2247 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -621,11 +621,6 @@ void STDCALL mysql_server_end()
   my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
   copy_arguments_ptr=0;
   clean_up(0);
-#ifdef THREAD
-  /* Don't call my_thread_end() if the application is using MY_INIT() */
-  if (!org_my_init_done)
-    my_thread_end();
-#endif
   /* If library called my_init(), free memory allocated by it */
   if (!org_my_init_done)
     my_end(0);
diff --git a/mysys/charset.c b/mysys/charset.c
index 6a64730571cb1e8f3b6ad4634417f0306e1dffa3..ba6733185e081d2750e32078f423261c19b495aa 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -453,20 +453,37 @@ static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s)
 
 static void charset_append(DYNAMIC_STRING *s, const char *name)
 {
-  if (!charset_in_string(name, s)) {
+  if (!charset_in_string(name, s))
+  {
     dynstr_append(s, name);
     dynstr_append(s, " ");
   }
 }
 
 
-/* Returns a dynamically-allocated string listing the character sets
-   requested.  The caller is responsible for freeing the memory. */
+/*
+  Returns a dynamically-allocated string listing the character sets
+  requested.
+
+  SYNOPSIS
+    list_charsets()
+    want_flags		Flags for which character sets to return:
+			MY_COMPILED_SETS:	Return incompiled charsets    
+			MY_INDEX_SETS:
+			MY_LOADED_SETS:
+
+  NOTES
+    The caller is responsible for freeing the memory.
+
+
+  RETURN
+    A string with available character sets separated by space
+*/
 
 char * list_charsets(myf want_flags)
 {
   DYNAMIC_STRING s;
-  char *p;
+  char *result;
 
   (void)init_available_charsets(MYF(0));
   init_dynamic_string(&s, NullS, 256, 1024);
@@ -483,42 +500,45 @@ char * list_charsets(myf want_flags)
 
   if (want_flags & MY_CONFIG_SETS)
   {
-    CS_ID **c;
+    CS_ID **charset;
     char buf[FN_REFLEN];
     MY_STAT status;
 
-    if((c=available_charsets))
-      for (; *c; ++c)
-	{
-	  if (charset_in_string((*c)->name, &s))
-	    continue;
-	  get_charset_conf_name((*c)->number, buf);
-	  if (!my_stat(buf, &status, MYF(0)))
-	    continue;       /* conf file doesn't exist */
-	  dynstr_append(&s, (*c)->name);
-	  dynstr_append(&s, " ");
-	}
+    if ((charset=available_charsets))
+    {
+      for (; *charset; charset++)
+      {
+	if (charset_in_string((*charset)->name, &s))
+	  continue;
+	get_charset_conf_name((*charset)->number, buf);
+	if (!my_stat(buf, &status, MYF(0)))
+	  continue;       /* conf file doesn't exist */
+	dynstr_append(&s, (*charset)->name);
+	dynstr_append(&s, " ");
+      }
+    }
   }
 
   if (want_flags & MY_INDEX_SETS)
   {
-    CS_ID **c;
-    for (c = available_charsets; *c; ++c)
-      charset_append(&s, (*c)->name);
+    CS_ID **charset;
+    for (charset = available_charsets; *charset; charset++)
+      charset_append(&s, (*charset)->name);
   }
 
   if (want_flags & MY_LOADED_SETS)
   {
     uint i;
     for (i = 0; i < cs_info_table.elements; i++)
-      charset_append(&s, 
+      charset_append(&s,
 		     dynamic_element(&cs_info_table, i, CHARSET_INFO *)->name);
   }
-  s.str[s.length - 1] = '\0';   /* chop trailing space */
-  p = my_strdup(s.str, MYF(MY_WME));
+  if (s.length)
+    s.length--;					/* Remove end space */
+  result= my_strdup_with_length(s.str, s.length, MYF(MY_WME));
   dynstr_free(&s);
 
-  return p;
+  return result;
 }
 
 /****************************************************************************
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 59466083b285a8f470ea232f4f370730f53f2271..9f64e9dcb607f6abda5318441b2ab01c3698efb6 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -159,6 +159,7 @@ my_bool my_thread_init(void)
   tmp->id= ++thread_id;
   pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
   pthread_cond_init(&tmp->suspend, NULL);
+  tmp->init= 1;
 
 end:
 #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
@@ -170,12 +171,14 @@ my_bool my_thread_init(void)
 
 void my_thread_end(void)
 {
-  struct st_my_thread_var *tmp=my_thread_var;
+  struct st_my_thread_var *tmp;
+  tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
+
 #ifdef EXTRA_DEBUG_THREADS
   fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
 	  tmp,pthread_self());
 #endif  
-  if (tmp)
+  if (tmp && tmp->init)
   {
 #if !defined(DBUG_OFF)
     /* tmp->dbug is allocated inside DBUG library */
@@ -191,6 +194,8 @@ void my_thread_end(void)
     pthread_mutex_destroy(&tmp->mutex);
 #if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
     free(tmp);
+#else
+    tmp->init= 0;
 #endif
   }
   /* The following free has to be done, even if my_thread_var() is 0 */
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 6498a52cc0978c853cce2a0bb7800d614c3c705d..a217d40246f575fb4a2114539e2fa9f5db34ab5a 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -22,7 +22,11 @@
 #include "sql_select.h"
 #include <hash.h>
 #include <thr_alarm.h>
+#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H)
 #include <malloc.h>
+#elif defined(HAVE_MALLINFO) && defined(HAVE_SYS_MALLOC_H)
+#include <sys/malloc.h>
+#endif
 
 /* Intern key cache variables */
 extern "C" pthread_mutex_t THR_LOCK_keycache;