From c05267facaba6d42c9e86a44b0c413908c781a7e Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 11 Jun 2013 22:21:38 +0200 Subject: [PATCH] slcanpty: probe stdin capabilities at startup /dev/null returns EOF therefore select() finishes immediately. Now EOF is probed on start. Other /dev/null as stdin workarounds: - lscanpty ... < /dev/ptmx (dirty but works) - cat Signed-off-by: Oliver Hartkopp --- slcanpty.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/slcanpty.c b/slcanpty.c index 8a11473..2c1cabe 100644 --- a/slcanpty.c +++ b/slcanpty.c @@ -64,7 +64,7 @@ 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; @@ -386,6 +386,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) { @@ -395,6 +416,7 @@ int main(int argc, char **argv) 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 +438,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) { @@ -489,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); -- 2.39.2