THRIFT-2414 c_glib fix several bug
Patch: Jaesang Kim
diff --git a/.gitignore b/.gitignore
index eabb198..90d5308 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@
 .pydevproject
 .sonar
 .DS_Store
+.svn
 
 /contrib/.vagrant/
 /autoscan.log
diff --git a/compiler/cpp/src/generate/t_c_glib_generator.cc b/compiler/cpp/src/generate/t_c_glib_generator.cc
index 373e6a8..639f479 100644
--- a/compiler/cpp/src/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/generate/t_c_glib_generator.cc
@@ -490,10 +490,7 @@
 
   return ttype->is_container()
          || ttype->is_struct()
-         || ttype->is_xception()
-         || (ttype->is_base_type()
-             && (((t_base_type *) ttype)->get_base()
-                  == t_base_type::TYPE_STRING));
+         || ttype->is_xception();
 }
 
 
@@ -1436,7 +1433,7 @@
 
       f_service_ << endl <<
         indent() << "gint32 rseqid;" << endl <<
-        indent() << "gchar * fname;" << endl <<
+        indent() << "gchar * fname = NULL;" << endl <<
         indent() << "ThriftMessageType mtype;" << endl <<
         indent() << "ThriftProtocol * protocol = " << 
                       this->nspace_uc << service_name_uc <<
@@ -1822,7 +1819,7 @@
 	f_types_impl_ << indent() << "}" << endl;
       } else if (t->is_list()) {
         t_type *etype = ((t_list *) t)->get_elem_type();
-        string destructor_function = "g_ptr_array_free";
+        string destructor_function = "g_ptr_array_unref";
 
         if (etype->is_base_type()) {
           t_base_type::t_base tbase = ((t_base_type *) etype)->get_base();
@@ -1835,7 +1832,7 @@
             case t_base_type::TYPE_I32:           
             case t_base_type::TYPE_I64:
             case t_base_type::TYPE_DOUBLE:
-              destructor_function = "g_array_free";
+              destructor_function = "g_array_unref";
               break;
             case t_base_type::TYPE_STRING:
               break;
@@ -1849,7 +1846,7 @@
         indent_up();
         f_types_impl_ <<
           indent() << destructor_function << " (tobject->" << name <<
-                       ", TRUE);" << endl;
+                       ");" << endl;
         f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
         indent_down();
         f_types_impl_ << indent() << "}" << endl;
@@ -1873,7 +1870,7 @@
       f_types_impl_ << indent() << "{" << endl;
       indent_up();
       f_types_impl_ <<
-      indent() << "g_free (tobject->" << name << ");" << endl;
+      indent() << generate_free_func_from_type(t) << "(tobject->" << name << ");" << endl;
       f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
       indent_down();
       f_types_impl_ << indent() << "}" << endl;
@@ -2859,6 +2856,9 @@
       case t_base_type::TYPE_DOUBLE:
         return "NULL";
       case t_base_type::TYPE_STRING:
+        if (((t_base_type *) ttype)->is_binary()) {
+            return "thrift_string_free";
+        }
         return "g_free";
       default:
         throw "compiler error: no hash table info for type";
diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy
old mode 100755
new mode 100644
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
index da59628..32a8000 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
@@ -806,6 +806,7 @@
     }
     xfer += ret;
   } else {
+    *len = (guint32) read_len;
     *buf = NULL;
   }
 
diff --git a/lib/c_glib/src/thrift/c_glib/thrift.c b/lib/c_glib/src/thrift/c_glib/thrift.c
index 0051df0..079cb51 100644
--- a/lib/c_glib/src/thrift/c_glib/thrift.c
+++ b/lib/c_glib/src/thrift/c_glib/thrift.c
@@ -30,3 +30,9 @@
   *list = g_list_append (*list, key);
 }
 
+void
+thrift_string_free (gpointer str)
+{
+	GByteArray* ptr = str;
+	g_byte_array_unref(ptr);
+}
diff --git a/lib/c_glib/src/thrift/c_glib/thrift.h b/lib/c_glib/src/thrift/c_glib/thrift.h
index 0636a2f..236b46f 100644
--- a/lib/c_glib/src/thrift/c_glib/thrift.h
+++ b/lib/c_glib/src/thrift/c_glib/thrift.h
@@ -33,5 +33,6 @@
 
 void thrift_hash_table_get_keys (gpointer key, gpointer value,
                                  gpointer user_data);
+void thrift_string_free (gpointer str);
 
 #endif // #ifndef _THRIFT_THRIFT_H
diff --git a/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c b/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c
index 2b8b395..64bd87a 100644
--- a/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c
+++ b/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c
@@ -171,9 +171,23 @@
 }
 
 void
+thrift_application_exception_finalize (GObject *object)
+{
+  ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object);
+
+  if (tae->__isset_message) {
+		g_free(tae->message);
+  }
+}
+
+void
 thrift_application_exception_class_init (ThriftApplicationExceptionClass *class)
 {
+  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
   ThriftStructClass *cls = THRIFT_STRUCT_CLASS(class);
+
   cls->read = thrift_application_exception_read;
   cls->write = thrift_application_exception_write;
+
+  gobject_class->finalize = thrift_application_exception_finalize;
 }
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c
index a32e5ad..d6b67ed 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c
@@ -69,6 +69,7 @@
                                      guint32 len, GError **error)
 {
   ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport);
+  gint ret = 0;
   guint32 want = len;
   guint32 got = 0;
   guchar tmpdata[len];
@@ -90,19 +91,25 @@
   // enough to satisfy the read.
   if (t->r_buf_size < want)
   {
-    got += THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+    if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
                                                             tmpdata,
                                                             want,
-                                                            error);
+                                                            error)) < 0) {
+		return ret;
+	}
+	got += ret;
 
     // copy the data starting from where we left off
     memcpy (buf + have, tmpdata, got);
     return got + have; 
   } else {
-    got += THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
+    if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
                                                             tmpdata,
                                                             want,
-                                                            error);
+                                                            error)) < 0) {
+		return ret;
+	}
+	got += ret;
     t->r_buf = g_byte_array_append (t->r_buf, tmpdata, got);
     
     // hand over what we have up to what the caller wants
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
index 694a84c..a371ace 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
@@ -54,20 +54,21 @@
 gboolean
 thrift_socket_open (ThriftTransport *transport, GError **error)
 {
-  struct hostent *hp = NULL;
+  struct hostent he, *hp = NULL;
   struct sockaddr_in pin;
+  int err;
+  char buf[1024];
 
   ThriftSocket *tsocket = THRIFT_SOCKET (transport);
   g_return_val_if_fail (tsocket->sd == 0, FALSE);
 
   /* lookup the destination host */
-  if ((hp = gethostbyname (tsocket->hostname)) == NULL)
-  {
+  if (gethostbyname_r(tsocket->hostname, &he, buf, 1024, &hp, &err) != 0 || hp == NULL) {
     /* host lookup failed, bail out with an error */
     g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_HOST,
                  "host lookup failed for %s:%d - %s",
                  tsocket->hostname, tsocket->port,
-                 hstrerror (h_errno));
+                 hstrerror (err));
     return FALSE;
   }
 
@@ -130,7 +131,7 @@
   while (got < len)
   {
     ret = recv (socket->sd, buf+got, len-got, 0);
-    if (ret < 0)
+    if (ret <= 0)
     {
       g_set_error (error, THRIFT_TRANSPORT_ERROR,
                    THRIFT_TRANSPORT_ERROR_RECEIVE,