]> rtime.felk.cvut.cz Git - can-utils.git/blobdiff - slcanpty.c
candump: Enable HW timestamping before using it
[can-utils.git] / slcanpty.c
index dece1e1cc680fc1e86b73e70cb4d694a4c46e722..5cf14ef9837450262be6220f1af28e453c0f364d 100644 (file)
@@ -64,11 +64,11 @@ static int asc2nibble(char c)
 
 /* read data from pty, send CAN frames to CAN socket and answer commands */
 int pty2can(int pty, int socket, struct can_filter *fi,
-              int *is_open, int *tstamp)
+           int *is_open, int *tstamp)
 {
        int nbytes;
        char cmd;
-       char buf[200];
+       static char buf[200];
        char replybuf[10]; /* for answers to received commands */
        int ptr;
        struct can_frame frame;
@@ -185,6 +185,13 @@ rx_restart:
                ptr = 1;
                goto rx_out;
        }
+       /* check for 'v'ersion command */
+       if (cmd == 'v') {
+               sprintf(replybuf, "v1014\r");
+               tmp = strlen(replybuf);
+               ptr = 1;
+               goto rx_out;
+       }
 
        /* check for serial 'N'umber command */
        if (cmd == 'N') {
@@ -386,6 +393,27 @@ int can2pty(int pty, int socket, int *tstamp)
        return 0;
 }
 
+int check_select_stdin(void)
+{
+       fd_set rdfs;
+       struct timeval timeout;
+       int ret;
+
+       FD_ZERO(&rdfs);
+       FD_SET(0, &rdfs);
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 0;
+
+       ret = select(1, &rdfs, NULL, NULL, &timeout);
+
+       if (ret < 0)
+               return 0; /* not selectable */
+
+       if (ret > 0 && getchar() == EOF)
+               return 0; /* EOF, eg. /dev/null */
+
+       return 1;
+}
 
 int main(int argc, char **argv)
 {
@@ -394,7 +422,7 @@ int main(int argc, char **argv)
        int s; /* can raw socket */ 
        struct sockaddr_can addr;
        struct termios topts;
-       struct ifreq ifr;
+       int select_stdin = 0;
        int running = 1;
        int tstamp = 0;
        int is_open = 0;
@@ -416,6 +444,8 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       select_stdin = check_select_stdin();
+
        /* open pty */
        p = open(argv[1], O_RDWR);
        if (p < 0) {
@@ -430,7 +460,9 @@ int main(int argc, char **argv)
 
        /* disable local echo which would cause double frames */
        topts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK |
-                          ECHONL | ECHOPRT | ECHOKE | ICRNL);
+                          ECHONL | ECHOPRT | ECHOKE);
+       topts.c_iflag &= ~(ICRNL);
+       topts.c_iflag |= INLCR;
        tcsetattr(p, TCSANOW, &topts);
 
        /* Support for the Unix 98 pseudo-terminal interface /dev/ptmx /dev/pts/N */
@@ -464,13 +496,7 @@ int main(int argc, char **argv)
        }
 
        addr.can_family = AF_CAN;
-
-       strcpy(ifr.ifr_name, argv[2]);
-       if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
-               perror("SIOCGIFINDEX");
-               return 1;
-       }
-       addr.can_ifindex = ifr.ifr_ifindex;
+       addr.can_ifindex = if_nametoindex(argv[2]);
 
        /* disable reception of CAN frames until we are opened by 'O' */
        setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
@@ -487,7 +513,10 @@ int main(int argc, char **argv)
        while (running) {
 
                FD_ZERO(&rdfs);
-               FD_SET(0, &rdfs);
+
+               if (select_stdin)
+                       FD_SET(0, &rdfs);
+
                FD_SET(p, &rdfs);
                FD_SET(s, &rdfs);