diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-03-31 10:53:32 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-03-31 14:33:18 +0200 |
commit | 98af3c3a6df8fc6e8ef765b30aff2a013b9904fa (patch) | |
tree | ccf17e6985872dd4778f6ead301f02b03c7ebc86 /tests | |
parent | 36106ae24475f5742dd3335c1bbe4d5e5321912e (diff) |
ipa: Change ipa_msg_recv() to support partial receive
Currently ipa_msg_recv() fails, when messages are received partially.
This patch provides a new function ipa_msg_recv_buffered() that uses
an additional ** to a message buffer to store partial data. When
this happens, -EAGAIN is returned. If NULL is used, the function
behaves similar to ipa_msg_recv() and fails on partial read.
In addition in case of errors the return value is now always -EXXX
and the contents of errno is undefined.
Note that this feature needs support by the calling code insofar that
*tmp_msg must be set to NULL initially and it must be freed and
set to NULL manually when the socket is closed.
Note also that ipa_msg_recv() is then a wrapper around
ipa_msg_recv_buffered() which mimics the old error behaviour by
setting errno explicitely to -rc and returning -1 when an error has
happened.
Ticket: OW#728
Sponsored-by: On-Waves ehf
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ipa_recv/ipa_recv_test.c | 55 | ||||
-rw-r--r-- | tests/ipa_recv/ipa_recv_test.ok | 27 |
2 files changed, 64 insertions, 18 deletions
diff --git a/tests/ipa_recv/ipa_recv_test.c b/tests/ipa_recv/ipa_recv_test.c index af87c27..0f56926 100644 --- a/tests/ipa_recv/ipa_recv_test.c +++ b/tests/ipa_recv/ipa_recv_test.c @@ -65,7 +65,7 @@ static void append_ipa_message(struct msgb *msg, int proto, const char *text) strcpy((char *)l2, text); } -static int receive_messages(int fd) +static int receive_messages(int fd, struct msgb **pending_msg) { struct msgb *msg; char dummy; @@ -76,13 +76,22 @@ static int receive_messages(int fd) break; } msg = NULL; - rc = ipa_msg_recv(fd, &msg); - if (rc == -1) - rc = -errno; + rc = ipa_msg_recv_buffered(fd, &msg, pending_msg); + fprintf(stderr, - "ipa_msg_recv: %d, msg %s NULL\n", - rc, msg ? "!=" : "=="); - if (rc == -EAGAIN) + "ipa_msg_recv_buffered: %d, msg %s NULL, " + "pending_msg %s NULL\n", + rc, msg ? "!=" : "==", + !pending_msg ? "??" : *pending_msg ? "!=" : "=="); + if (pending_msg && !!msg == !!*pending_msg) + printf( "got msg %s NULL, pending_msg %s NULL, " + "returned: %s\n", + msg ? "!=" : "==", + *pending_msg ? "!=" : "==", + rc == 0 ? "EOF" : + rc > 0 ? "OK" : + strerror(-rc)); + else if (!pending_msg && rc == -EAGAIN) printf( "got msg %s NULL, " "returned: %s\n", msg ? "!=" : "==", @@ -94,7 +103,8 @@ static int receive_messages(int fd) if (rc == -EAGAIN) break; if (rc < 0) { - printf("ipa_msg_recv failed with: %s\n", strerror(-rc)); + printf("ipa_msg_recv_buffered failed with: %s\n", + strerror(-rc)); return rc; } printf("got IPA message, size=%d, proto=%d, text=\"%s\"\n", @@ -121,13 +131,15 @@ static int slurp_data(int fd) { return count; }; -static void test_complete_recv(void) +static void test_complete_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with complete messages.\n"); + printf("Testing IPA recv with complete messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -145,7 +157,11 @@ static void test_complete_recv(void) } for (i=0; i < ARRAY_SIZE(ipa_test_messages); i++) { - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); + if (pending_msg) + printf("Unexpected partial message: size=%d\n", + pending_msg->len); if (rc == 0) break; @@ -160,16 +176,19 @@ static void test_complete_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } -static void test_partial_recv(void) +static void test_partial_recv(int do_not_assemble) { int sv[2]; struct msgb *msg_out = msgb_alloc(4096, "msg_out"); + struct msgb *pending_msg = NULL; int rc, i; - printf("Testing IPA recv with partitioned messages.\n"); + printf("Testing IPA recv with partitioned messages%s.\n", + do_not_assemble ? "" : " with assembling enabled"); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) err(1, "socketpair"); @@ -190,7 +209,8 @@ static void test_partial_recv(void) if (msg_out->len == 0) shutdown(sv[1], SHUT_WR); - rc = receive_messages(sv[0]); + rc = receive_messages(sv[0], + do_not_assemble ? NULL : &pending_msg); if (rc == 0) break; @@ -205,6 +225,7 @@ static void test_partial_recv(void) close(sv[0]); msgb_free(msg_out); + msgb_free(pending_msg); } static struct log_info info = {}; @@ -218,8 +239,10 @@ int main(int argc, char **argv) printf("Testing the IPA layer.\n"); /* run the tests */ - test_complete_recv(); - test_partial_recv(); + test_complete_recv(1); + test_partial_recv(1); + test_complete_recv(0); + test_partial_recv(0); printf("No crashes.\n"); return 0; diff --git a/tests/ipa_recv/ipa_recv_test.ok b/tests/ipa_recv/ipa_recv_test.ok index 4144d47..bdbfb7d 100644 --- a/tests/ipa_recv/ipa_recv_test.ok +++ b/tests/ipa_recv/ipa_recv_test.ok @@ -5,8 +5,31 @@ got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMN got IPA message, size=16, proto=200, text="Hello again IPA" got IPA message, size=1, proto=200, text="" got IPA message, size=14, proto=200, text="Next is empty" -done: unread 14, unsent 0 +got msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 Testing IPA recv with partitioned messages. -ipa_msg_recv failed with: Input/output error +ipa_msg_recv_buffered failed with: Input/output error done: unread 0, unsent 154 +Testing IPA recv with complete messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 +Testing IPA recv with partitioned messages with assembling enabled. +got IPA message, size=10, proto=200, text="Hello IPA" +got IPA message, size=86, proto=200, text="A longer test message. ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" +got IPA message, size=16, proto=200, text="Hello again IPA" +got IPA message, size=1, proto=200, text="" +got IPA message, size=14, proto=200, text="Next is empty" +got msg == NULL, pending_msg == NULL, returned: Resource temporarily unavailable +got IPA message, size=4, proto=200, text="Bye" +got IPA message, size=4, proto=200, text="Bye" +done: unread 0, unsent 0 No crashes. |