From 719b834a792641d2b119dac1b8c087b67ce08e31 Mon Sep 17 00:00:00 2001
From: Dmitry Simonenko <pmwkaa@gmail.com>
Date: Fri, 16 Dec 2011 15:42:36 +0400
Subject: [PATCH] connector/c: tnt_call no args fix, test added

---
 connector/c/tnt/tnt_call.c        | 12 ++++++++++--
 connector/c/tntnet/tnt_io.c       |  8 ++++----
 test/connector_c/connector.result |  1 +
 test/connector_c/tt.c             | 18 ++++++++++++++++++
 4 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/connector/c/tnt/tnt_call.c b/connector/c/tnt/tnt_call.c
index 13e0f89fc7..23bf002c71 100644
--- a/connector/c/tnt/tnt_call.c
+++ b/connector/c/tnt/tnt_call.c
@@ -65,6 +65,8 @@ tnt_call(struct tnt_stream *s, uint32_t flags, char *proc,
 	hdr.type = TNT_OP_CALL;
 	hdr.len = sizeof(struct tnt_header_call) +
 		  proc_enc_size + proc_len + args->size;
+	if (args->size == 0)
+		hdr.len += 4;
 	hdr.reqid = s->reqid;
 	/* filling call header */
 	struct tnt_header_call hdr_call;
@@ -79,7 +81,13 @@ tnt_call(struct tnt_stream *s, uint32_t flags, char *proc,
 	v[2].iov_len  = proc_enc_size;
 	v[3].iov_base = proc;
 	v[3].iov_len  = proc_len;
-	v[4].iov_base = args->data;
-	v[4].iov_len  = args->size;
+	if (args->size == 0) {
+		uint32_t argc = 0;
+		v[4].iov_base = &argc;
+		v[4].iov_len  = 4;
+	} else {
+		v[4].iov_base = args->data;
+		v[4].iov_len  = args->size;
+	}
 	return s->writev(s, v, 5);
 }
diff --git a/connector/c/tntnet/tnt_io.c b/connector/c/tntnet/tnt_io.c
index ea04533311..abee2ec67b 100644
--- a/connector/c/tntnet/tnt_io.c
+++ b/connector/c/tntnet/tnt_io.c
@@ -251,10 +251,10 @@ tnt_io_send_raw(struct tnt_stream_net *s, char *buf, size_t size, int all)
 	do {
 		ssize_t r;
 		if (s->sbuf.tx) {
-			r = s->sbuf.tx(s->sbuf.buf, buf, size);
+			r = s->sbuf.tx(s->sbuf.buf, buf + off, size - off);
 		} else {
 			do {
-				r = send(s->fd, buf, size, 0);
+				r = send(s->fd, buf + off, size - off, 0);
 			} while (r == -1 && (errno == EINTR));
 		}
 		if (r <= 0) {
@@ -368,10 +368,10 @@ tnt_io_recv_raw(struct tnt_stream_net *s, char *buf, size_t size, int all)
 	do {
 		ssize_t r;
 		if (s->rbuf.tx) {
-			r = s->rbuf.tx(s->rbuf.buf, buf, size);
+			r = s->rbuf.tx(s->rbuf.buf, buf + off, size - off);
 		} else {
 			do {
-				r = recv(s->fd, buf, size, 0);
+				r = recv(s->fd, buf + off, size - off, 0);
 			} while (r == -1 && (errno == EINTR));
 		}
 		if (r <= 0) {
diff --git a/test/connector_c/connector.result b/test/connector_c/connector.result
index e238fef4b9..922997eee8 100644
--- a/test/connector_c/connector.result
+++ b/test/connector_c/connector.result
@@ -13,6 +13,7 @@
 > select                        [OK]
 > delete                        [OK]
 > call                          [OK]
+> call (no args)                [OK]
 > reply                         [OK]
 > lex ws                        [OK]
 > lex integer                   [OK]
diff --git a/test/connector_c/tt.c b/test/connector_c/tt.c
index f0579d22bf..0a26916796 100644
--- a/test/connector_c/tt.c
+++ b/test/connector_c/tt.c
@@ -425,6 +425,23 @@ static void tt_tnt_net_call(struct tt_test *test) {
 	tnt_iter_free(&i);
 }
 
+/* call (no args) */
+static void tt_tnt_net_call_na(struct tt_test *test) {
+	struct tnt_tuple args;
+	tnt_tuple_init(&args);
+	TT_ASSERT(tnt_call(&net, 0, "box.insert", &args) > 0);
+	TT_ASSERT(tnt_flush(&net) > 0);
+	tnt_tuple_free(&args);
+	struct tnt_iter i;
+	tnt_iter_stream(&i, &net);
+	while (tnt_next(&i)) {
+		struct tnt_reply *r = TNT_ISTREAM_REPLY(&i);
+		TT_ASSERT(r->code != 0);
+		TT_ASSERT(strcmp(r->error, "Illegal parameters, tuple cardinality is 0") == 0);
+	}
+	tnt_iter_free(&i);
+}
+
 /* reply */
 static void tt_tnt_net_reply(struct tt_test *test) {
 	struct tnt_tuple kv1, kv2;
@@ -866,6 +883,7 @@ main(int argc, char * argv[])
 	tt_test(&t, "select", tt_tnt_net_select);
 	tt_test(&t, "delete", tt_tnt_net_delete);
 	tt_test(&t, "call", tt_tnt_net_call);
+	tt_test(&t, "call (no args)", tt_tnt_net_call_na);
 	tt_test(&t, "reply", tt_tnt_net_reply);
 	/* sql lexer */
 	tt_test(&t, "lex ws", tt_tnt_lex_ws);
-- 
GitLab