slcanpty: handle incomplete messages from pty correctly

Make sure that we have minimum one complete SLCAN messages from pty in the
receive buffer before we start processing the received SLCAN message.

Fragments of a received incomplete message are stored to be appended by the
next read() syscall in pty2can().

This patch is a rework of an initial patch from Ulrich Escher. Tnx!

Reported-by: Ulrich Escher <git@myvdr.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
pull/1/head
Oliver Hartkopp 2013-06-08 12:57:17 +02:00
parent 704d5f22d1
commit c9422deb0b
1 changed files with 21 additions and 1 deletions

View File

@ -73,8 +73,9 @@ int pty2can(int pty, int socket, struct can_filter *fi,
int ptr;
struct can_frame frame;
int tmp, i;
static int rxoffset = 0; /* points to the end of an received incomplete SLCAN message */
nbytes = read(pty, &buf, sizeof(buf)-1);
nbytes = read(pty, &buf[rxoffset], sizeof(buf)-rxoffset-1);
if (nbytes <= 0) {
/* nbytes == 0 : no error but pty decriptor has been closed */
if (nbytes < 0)
@ -83,6 +84,10 @@ int pty2can(int pty, int socket, struct can_filter *fi,
return 1;
}
/* reset incomplete message offset */
nbytes += rxoffset;
rxoffset = 0;
rx_restart:
/* remove trailing '\r' characters to be robust against some apps */
while (buf[0] == '\r' && nbytes > 0) {
@ -94,6 +99,21 @@ rx_restart:
if (!nbytes)
return 0;
/* check if we can detect a complete SLCAN message including '\r' */
for (tmp = 0; tmp < nbytes; tmp++) {
if (buf[tmp] == '\r')
break;
}
/* no '\r' found in the message buffer? */
if (tmp == nbytes) {
/* save incomplete message */
rxoffset = nbytes;
/* leave here and read from pty again */
return 0;
}
cmd = buf[0];
buf[nbytes] = 0;