]> rtime.felk.cvut.cz Git - sojka/can-utils.git/commitdiff
slcanpty: handle incomplete messages from pty correctly
authorOliver Hartkopp <socketcan@hartkopp.net>
Sat, 8 Jun 2013 10:57:17 +0000 (12:57 +0200)
committerOliver Hartkopp <socketcan@hartkopp.net>
Sat, 8 Jun 2013 10:57:17 +0000 (12:57 +0200)
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>
slcanpty.c

index 028bf214bef76f1dee406c5e8aba7f42a34441d2..dece1e1cc680fc1e86b73e70cb4d694a4c46e722 100644 (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;