Merge pull request #27 from dgquintas/bind_error

fixes server_test
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
index a4d8880..3a2b9dd 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -96,6 +96,7 @@
   GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
                  (server, addr));
 
+  grpc_error **errors = NULL;
   err = grpc_blocking_resolve_address(addr, "https", &resolved);
   if (err != GRPC_ERROR_NONE) {
     goto error;
@@ -106,8 +107,9 @@
     goto error;
   }
 
-  grpc_error **errors = gpr_malloc(sizeof(*errors) * resolved->naddrs);
-  for (i = 0; i < resolved->naddrs; i++) {
+  const size_t naddrs = resolved->naddrs;
+  errors = gpr_malloc(sizeof(*errors) * naddrs);
+  for (i = 0; i < naddrs; i++) {
     errors[i] = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
         resolved->addrs[i].len, &port_temp);
@@ -122,27 +124,22 @@
   }
   if (count == 0) {
     char *msg;
-    gpr_asprintf(&msg, "No address added out of total %d resolved",
-                 resolved->naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
+    gpr_asprintf(&msg, "No address added out of total %d resolved", naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+    gpr_free(msg);
     goto error;
-  } else if (count != resolved->naddrs) {
+  } else if (count != naddrs) {
     char *msg;
     gpr_asprintf(&msg, "Only %d addresses added out of total %d resolved",
-                 count, resolved->naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
+                 count, naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
     gpr_free(msg);
 
     const char *warning_message = grpc_error_string(err);
     gpr_log(GPR_INFO, "WARNING: %s", warning_message);
     grpc_error_free_string(warning_message);
     /* we managed to bind some addresses: continue */
-  } else {
-    for (i = 0; i < resolved->naddrs; i++) {
-      GRPC_ERROR_UNREF(errors[i]);
-    }
   }
-  gpr_free(errors);
   grpc_resolved_addresses_destroy(resolved);
 
   /* Register with the server only upon success */
@@ -151,6 +148,7 @@
 
 /* Error path: cleanup and return */
 error:
+  GPR_ASSERT(err != GRPC_ERROR_NONE);
   if (resolved) {
     grpc_resolved_addresses_destroy(resolved);
   }
@@ -161,5 +159,10 @@
 
 done:
   grpc_exec_ctx_finish(&exec_ctx);
+  for (i = 0; i < naddrs; i++) {
+    GRPC_ERROR_UNREF(errors[i]);
+  }
+  GRPC_ERROR_UNREF(err);
+  gpr_free(errors);
   return port_num;
 }
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 2b9b9f0..0cc466e 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -94,6 +94,9 @@
                               grpc_error **referencing, size_t num_referencing);
 #define GRPC_ERROR_CREATE(desc) \
   grpc_error_create(__FILE__, __LINE__, desc, NULL, 0)
+
+// Create an error that references some other errors. This function adds a
+// reference to each error in errs - it does not consume an existing reference
 #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \
   grpc_error_create(__FILE__, __LINE__, desc, errs, count)
 
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index dca068f..db70fad 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -286,10 +286,7 @@
 
   GPR_ASSERT(addr_len < ~(socklen_t)0);
   if (bind(fd, addr, (socklen_t)addr_len) < 0) {
-    char *addr_str;
-    grpc_sockaddr_to_string(&addr_str, addr, 0);
-    gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
-    gpr_free(addr_str);
+    err = GRPC_OS_ERROR(errno, "bind");
     goto error;
   }
 
@@ -312,9 +309,11 @@
   if (fd >= 0) {
     close(fd);
   }
-  return grpc_error_set_int(
+  grpc_error *ret = grpc_error_set_int(
       GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
       GRPC_ERROR_INT_FD, fd);
+  GRPC_ERROR_UNREF(err);
+  return ret;
 }
 
 /* event manager callback when reads are ready */
@@ -538,6 +537,8 @@
         GRPC_ERROR_CREATE_REFERENCING("Failed to add port to server", errs,
                                       GPR_ARRAY_SIZE(errs)),
         GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
+    GRPC_ERROR_UNREF(errs[0]);
+    GRPC_ERROR_UNREF(errs[1]);
     gpr_free(addr_str);
     return err;
   }