slcand: add slcan_attach and UART settings
Hello Yegor,
as requested on GitHub here are my comments:
Quoted 48 lines
slcand takes settings known from
slcan_attachto configure CAN interface, like open/close channel, set bitrate etc. In addition -S option sets UART's baudrate. This way slcand combines three utilities in one: old slcand,slcan_attachand stty.Example: slcand -o -s8 -S 3000000 ttyUSB0
Signed-off-by Yegor Yefremov <[email protected]>--- slcand.c | 295 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 256 insertions(+), 39 deletions(-)slcand.c +5
-6@@ -40,16 +40,16 @@#include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> #include <fcntl.h> #include <syslog.h> #include <errno.h> #include <pwd.h> #include <signal.h> -#include <sys/socket.h> #include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> #include <net/if.h> +#include <termios.h> /* default slcan line discipline since Kernel 2.6.25 */ #define LDISC_N_SLCAN 17@@ -69,46 +69,126 @@#define EXIT_SUCCESS 0#define EXIT_FAILURE 1 + +void print_usage (char *prg) { -fprintf (stderr,"\nUsage: %s tty [name]\n\n" , prg); -fprintf (stderr,"Example:\n" ); -fprintf (stderr,"%s ttyUSB1\n" , prg);
slcand.c line 84
Quoted 10 lines
slcand.c +6
-1-fprintf (stderr,"%s ttyS0 can0\n" , prg); +fprintf (stderr,"\nUsage: %s [options] <tty> [canif-name]\n\n" , prg); +fprintf (stderr,"Options: -o (send open command 'O\\r')\n" ); + fprintf(stderr, " -c (send close command 'C\\r')\n"); + fprintf(stderr, " -f (read status flags with 'F\\r' to reset error states)\n"); + fprintf(stderr," -s <speed> (set CAN speed 0..8)\n" ); +fprintf (stderr," -S <speed> (set UART speed)\n" );
It would be nice for the user to know the range of the UART speed and it is in baud.
Quoted 19 lines
slcand.c +13
-0+fprintf (stderr," -b <btr> (set bit time register value)\n" ); + fprintf(stderr, " -F (stay in foreground; no daemonize)\n"); +fprintf (stderr," -h (show this help page)\n" ); +fprintf (stderr,"\nExamples:\n" ); +fprintf (stderr,"slcand -o -c -f -s6 ttyslcan0\n" ); +fprintf (stderr,"slcand -o -c -f -s6 ttyslcan0 can0\n" );fprintf (stderr,"\n" );exit (EXIT_FAILURE ); } + +static int slcand_running =0 ; +static int exit_code =0 ; +static char ttypath[TTYPATH_LENGTH ]; +static char pidfile[PIDFILE_LENGTH ]; + +static void child_handler (int signum)
slcand.c line 109
Quoted 10 lines
slcand.c +2
-4{switch (signum) { -case SIGALRM : -exit (EXIT_FAILURE ); -break ;case SIGUSR1 : -exit (EXIT_SUCCESS ); +/* exit parent */ +exit (EXIT_SUCCESS );
Please try to keep code convention.
Quoted 11 lines
slcand.c +7
-1break ; +case SIGALRM :case SIGCHLD : -exit (EXIT_FAILURE ); +syslog (LOG_NOTICE ,"received signal %i on %s" , signum, ttypath); + exit_code =EXIT_FAILURE ; + slcand_running =0 ; +break ; +case SIGINT : +case SIGTERM :
slcand.c line 128
Quoted 10 lines
slcand.c +4
-1+syslog (LOG_NOTICE ,"received signal %i on %s" , signum, ttypath); + exit_code =EXIT_SUCCESS ; + slcand_running =0 ;break ; } } -static void daemonize (const char *lockfile,char *tty) +static int look_up_uart_speed (int s)
As my comment on GitHub, i think int isn't 32 bit or high on all platforms. So please change the datatype of parameter s to make sure the maximum like 4000000 is always reached like long or int32_t. Btw speed would be a better variable name.
Quoted 42 lines
slcand.c +42
-0+{ +switch (s) { +case 9600 : +return B9600 ; +case 19200 : +return B19200 ; +case 38400 : +return B38400 ; +case 57600 : +return B57600 ; +case 115200 : +return B115200 ; +case 230400 : +return B230400 ; +case 460800 : +return B460800 ; +case 500000 : +return B500000 ; +case 576000 : +return B576000 ; +case 921600 : +return B921600 ; +case 1000000 : +return B1000000 ; +case 1152000 : +return B1152000 ; +case 1500000 : +return B1500000 ; +case 2000000 : +return B2000000 ; +#ifdef B2500000 +case 2500000 : +return B2500000 ; +#endif +#ifdef B3000000 +case 3000000 : +return B3000000 ; +#endif +#ifdef B3500000 +case 3500000 : +return B3500000 ; +#endif
slcand.c line 180
Quoted 10 lines
slcand.c +10
-0+#ifdef B3710000 + case 3710000 + return B3710000; +#endif +#ifdef B4000000 +case 4000000 : +return B4000000 ; +#endif +default : +return B57600 ;
I believe it isn't a good behaviour to return 57600 in error case. So better return a special error value like -1 and handle this error case.
Quoted 40 lines
slcand.c +5
-1+ } +} + +static pid_t daemonize (const char *lockfile,char *tty,char *name) {pid_t pid, sid, parent;int lfp =-1 ;FILE * pFile; +FILE * dummyFile;char const *pidprefix ="/var/run/" ;char const *pidsuffix =".pid" ; -char pidfile[PIDFILE_LENGTH ];snprintf (pidfile,PIDFILE_LENGTH ,"%s%s-%s%s" , pidprefix,DAEMON_NAME , tty, pidsuffix);/* already a daemon */ if (getppid () == 1)slcand.c +3
-1-return ; +return 0 ;/* Create the lock file as the current user */ if (lockfile && lockfile[0 ])@@ -134,6 +214,8 @@ static void daemonize (const char *lockfile, char *tty) }/* Trap signals that we expect to receive */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler);signal (SIGCHLD , child_handler);signal (SIGUSR1 , child_handler);signal (SIGALRM, child_handler);slcand.c +0
-0@@ -152,9 +234,8 @@ static void daemonize (const char *lockfile, char *tty)/* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
for two seconds to elapse (SIGALRM).pause()should not
return. */
slcand.c
Quoted 2 lines
slcand.c +1
-1-alarm (2 ); +alarm (5 );
Please correct the comment above, if you change the seconds.
Quoted 31 lines
pause ();slcand.c +2
-2-exit (EXIT_FAILURE ); }@@ -167,7 +248,8 @@ static void daemonize (const char *lockfile, char *tty)signal (SIGTTOU ,SIG_IGN );signal (SIGTTIN ,SIG_IGN );signal (SIGHUP ,SIG_IGN );/* Ignore hangup signal */ -signal (SIGTERM ,SIG_DFL );/* Die on SIGTERM */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler);/* Change the file mode mask */ umask (0);slcand.c +1
-1@@ -182,7 +264,7 @@ static void daemonize (const char *lockfile, char *tty) } pFile =fopen (pidfile,"w" ); -if (pFile ==NULL ) +if (NULL == pFile) { syslog (LOG_ERR, "unable to create pid file %s, code=%d (%s)",pidfile, errno, strerror (errno));slcand.c +0
-0@@ -201,36 +283,88 @@ static void daemonize (const char *lockfile, char *tty) }/* Redirect standard files to /dev/null */
slcand.c static void daemonize (const char *lockfile, · line 292
Quoted 10 lines
slcand.c +4
-4-freopen ("/dev/null" ,"r" , stdin); -freopen ("/dev/null" ,"w" , stdout); -freopen ("/dev/null" ,"w" , stderr); + dummyFile =freopen ("/dev/null" ,"r" , stdin); + dummyFile =freopen ("/dev/null" ,"w" , stdout); + dummyFile =freopen ("/dev/null" ,"w" , stderr);/* Tell the parent process that we are A-okay */ -kill (parent,SIGUSR1 ); +//kill (parent, SIGUSR1);
Why do you uncomment this line than remove it?
Quoted 54 lines
slcand.c +45
-1+return parent; }int main (int argc,char *argv[]) {char *tty =NULL ; -char ttypath[TTYPATH_LENGTH ];char const *devprefix ="/dev/" ;char *name =NULL ;char buf[IFNAMSIZ +1 ]; +struct termios tios; +speed_t old_ispeed; +speed_t old_ospeed; + +int opt; +int detach =1 ; +int send_open =0 ; +int send_close =0 ; +int send_read_status_flags =0 ; +char *speed =NULL ; +char *uart_speed_str =NULL ; +long int uart_speed =0 ; +char *btr =NULL ; +int run_as_daemon =1 ; +pid_t parent_pid =0 ; + + ttypath[0 ] ='\0' ; + +while ((opt =getopt (argc, argv,"ocfs:S:b:?hF" )) !=-1 ) { +switch (opt) { +case 'o' : + send_open =1 ; +break ; +case 'c' : + send_close =1 ; +break ; +case 'f' : + send_read_status_flags =1 ; +break ; +case 's' : + speed = optarg; +if (strlen (speed) >1 ) +print_usage (argv[0 ]); +break ; +case 'S' : + uart_speed_str = optarg; + errno =0 ; + uart_speed =strtol (uart_speed_str,NULL ,10 ); +if (errno) +print_usage (argv[0 ]); +break ; +case 'b' : + btr = optarg; +if (strlen (btr) >6 )
slcand.c static void daemonize (const char *lockfile, · line 355
Quoted 10 lines
slcand.c +10
-0+print_usage (argv[0 ]); +break ; +case 'F' : + run_as_daemon =0 ; +break ; +case 'h' : +case '?' : +default : +print_usage (argv[0 ]); +//exit(EXIT_SUCCESS);
dito
Quoted 26 lines
slcand.c +7
-9+break ; + } + }/* Initialize the logging interface */ openlog (DAEMON_NAME ,LOG_PID ,LOG_LOCAL5 ); -/* See how we're called */ -if (argc ==2 ) { - tty = argv[1 ]; - }else if (argc ==3 ) { - tty = argv[1 ]; - name = argv[2 ]; -if (strlen (name) >IFNAMSIZ -1 ) -print_usage (argv[0 ]); - }else { +/* Parse serial device name and optional can interface name */ + tty = argv[optind]; +if (NULL == tty) {print_usage (argv[0 ]); } + name = argv[optind +1 ];/* Prepare the tty device name string */ char * pch;
slcand.c int main (int argc, char *argv[]) · line 381
Quoted 6 lines
slcand.c +2
-1@@ -243,16 +377,69 @@ int main (int argc, char *argv[])syslog (LOG_INFO ,"starting on TTY device %s" , ttypath);/* Daemonize */ -daemonize ("/var/lock/" DAEMON_NAME , tty); +if (run_as_daemon) { + parent_pid =daemonize ("/var/lock/" DAEMON_NAME , tty, name);
I think /var/lock is a perfect candidate for a define.
Quoted 80 lines
slcand.c +54
-2+ } + else { +/* Trap signals that we expect to receive */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler); + } + +/* */ + slcand_running =1 ;/* Now we are a daemon -- do the work for which we were paid */ int fd;int ldisc =LDISC_N_SLCAN ; -if ((fd =open (ttypath,O_WRONLY |O_NOCTTY )) <0 ) { +if ((fd =open (ttypath,O_RDWR |O_NONBLOCK |O_NOCTTY )) <0 ) {syslog (LOG_NOTICE ,"failed to open TTY device %s\n" , ttypath);perror (ttypath); -exit (1 ); +exit (EXIT_FAILURE ); + } + +/* Configure baud rate */ +memset (&tios,0 ,sizeof (struct termios )); +if (tcgetattr (fd, &tios) <0 ) { + syslog (LOG_NOTICE, "failed to get attributes for TTY device %s: %s\n", ttypath, strerror(errno)); + exit (EXIT_FAILURE); + } + +/* Get old values for later restore */ + old_ispeed =cfgetispeed (&tios); + old_ospeed =cfgetospeed (&tios); + +/* Baud Rate */ +cfsetispeed (&tios,look_up_uart_speed (uart_speed)); +cfsetospeed (&tios,look_up_uart_speed (uart_speed)); + +/* apply changes */ + if(tcsetattr(fd, TCSADRAIN, &tios) < 0) { + syslog(LOG_NOTICE, "Cannot set attributes for device \"%s\": %s!\n", ttypath, strerror(errno)); + } + + if (speed) { + sprintf(buf, "C\rS%s\r", speed); + if(write(fd, buf, strlen(buf)) < 0) { + //syslog (LO, "failed to get attributes for TTY device %s: %s\n", ttypath, strerror(errno)); + + } + } + + if (btr) { + sprintf(buf, "C\rs%s\r", btr); + write(fd, buf, strlen(buf)); + } + + if (send_read_status_flags) { + sprintf(buf, "F\r"); + write(fd, buf, strlen(buf)); + } + + if (send_open) { + sprintf(buf, "O\r"); + write(fd, buf, strlen(buf));} /* set slcan like discipline on given tty */slcand.c +3
-2@@ -289,14 +476,44 @@ int main (int argc, char *argv[])close (s); } } +if (parent_pid >0 ) { +kill (parent_pid,SIGUSR1 ); + }/* The Big Loop */ -while (1 ) { -sleep (60 );/* wait 60 seconds */
slcand.c int main (int argc, char *argv[]) · line 493
Quoted 10 lines
slcand.c +10
-0+while (slcand_running) { +sleep (1 );/* wait 1 second */ + } + +/* Reset line discipline */ +syslog (LOG_INFO ,"stopping on TTY device %s" , ttypath); + ldisc =N_TTY ; +if (ioctl (fd,TIOCSETD , &ldisc) <0 ) { +perror ("ioctl TIOCSETD" ); +exit (1 );
Is here a EXIT_FAILURE missing?
Quoted 27 lines
slcand.c +20
-1+ } + +if (send_close) { +sprintf (buf,"C\r" ); +write (fd, buf,strlen (buf)); } +/* Reset old rates */ +cfsetispeed (&tios, old_ispeed); +cfsetospeed (&tios, old_ospeed); + +/* apply changes */ +if (tcsetattr (fd,TCSADRAIN , &tios) <0 ) { + syslog(LOG_NOTICE, "Cannot set attributes for device \"%s\": %s!\n", ttypath, strerror(errno)); + } + + /* Remove pidfile */ + if(run_as_daemon) { + unlink(pidfile); + } +/* Finish up */ syslog (LOG_NOTICE ,"terminated on %s" , ttypath);closelog (); -return 0 ; +return exit_code;
Quoted 2 lines
}
Best regards
Stefan Wahren
Hi Stefan, hi Oliver,
I've implemented some suggestions and sent v2, but there are some places, where I'm not sure how it should be really implemented, so I just left comments like "Oliver?".
Quoted 89 lines · Stefan Wahren
Hello Yegor,
as requested on GitHub here are my comments:
Quoted 46 lines
slcand takes settings known from
slcan_attachto configure CAN interface, like open/close channel, set bitrate etc. In addition -S option sets UART's baudrate. This way slcand combines three utilities in one: old slcand,slcan_attachand stty.Example: slcand -o -s8 -S 3000000 ttyUSB0
Signed-off-by Yegor Yefremov <[email protected]>--- slcand.c | 295 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 256 insertions(+), 39 deletions(-)slcand.c +5
-4@@ -40,16 +40,16 @@#include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> #include <fcntl.h> #include <syslog.h> #include <errno.h> #include <pwd.h> #include <signal.h> -#include <sys/socket.h> #include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> #include <net/if.h> +#include <termios.h> /* default slcan line discipline since Kernel 2.6.25 */ #define LDISC_N_SLCAN 17@@ -69,46 +69,126 @@#define EXIT_SUCCESS 0#define EXIT_FAILURE 1 + +void print_usage (char *prg) { -fprintf (stderr,"\nUsage: %s tty [name]\n\n" , prg);slcand.c line 82
Quoted 10 lines
slcand.c +6
-3-fprintf (stderr,"Example:\n" ); -fprintf (stderr,"%s ttyUSB1\n" , prg); -fprintf (stderr,"%s ttyS0 can0\n" , prg); +fprintf (stderr,"\nUsage: %s [options] <tty> [canif-name]\n\n" , prg); +fprintf (stderr,"Options: -o (send open command 'O\\r')\n" ); +fprintf (stderr," -c (send close command 'C\\r')\n" ); + fprintf(stderr, " -f (read status flags with 'F\\r' to reset error states)\n"); +fprintf (stderr," -s <speed> (set CAN speed 0..8)\n" ); +fprintf (stderr," -S <speed> (set UART speed)\n" );It would be nice for the user to know the range of the UART speed and it is in baud.
Quoted 24 lines
slcand.c +13
-2+fprintf (stderr," -b <btr> (set bit time register value)\n" ); + fprintf(stderr, " -F (stay in foreground; no daemonize)\n"); + fprintf(stderr," -h (show this help page)\n" ); +fprintf (stderr,"\nExamples:\n" ); +fprintf (stderr,"slcand -o -c -f -s6 ttyslcan0\n" ); +fprintf (stderr,"slcand -o -c -f -s6 ttyslcan0 can0\n" );fprintf (stderr,"\n" );exit (EXIT_FAILURE ); } + +static int slcand_running =0 ; +static int exit_code =0 ; +static char ttypath[TTYPATH_LENGTH ]; +static char pidfile[PIDFILE_LENGTH ]; + +static void child_handler (int signum) {switch (signum) { -case SIGALRM : -exit (EXIT_FAILURE );
Quoted 8 lines
slcand.c line 107
Quoted 5 lines
slcand.c +2
-2-break ;case SIGUSR1 : -exit (EXIT_SUCCESS ); +/* exit parent */ +exit (EXIT_SUCCESS );Please try to keep code convention.
Fixed
Quoted 17 lines
Quoted 17 lines
slcand.c +10
-1break ; +case SIGALRM :case SIGCHLD : -exit (EXIT_FAILURE ); +syslog (LOG_NOTICE ,"received signal %i on %s" , signum, ttypath); + exit_code =EXIT_FAILURE ; + slcand_running =0 ; +break ; +case SIGINT : +case SIGTERM : +syslog (LOG_NOTICE ,"received signal %i on %s" , signum, ttypath); + exit_code =EXIT_SUCCESS ; + slcand_running =0 ;break ; } }
Quoted 8 lines
slcand.c line 124
Quoted 2 lines
slcand.c +1
-1-static void daemonize (const char *lockfile,char *tty) +static int look_up_uart_speed (int s)As my comment on GitHub, i think int isn't 32 bit or high on all platforms. So please change the datatype of parameter s to make sure the maximum like 4000000 is always reached like long or
int32_t. Btw speed would be a better variable name.
Fixed. speed refers to CAN speed.
Quoted 48 lines
Quoted 48 lines
slcand.c +48
-0+{ +switch (s) { +case 9600 : +return B9600 ; +case 19200 : +return B19200 ; +case 38400 : +return B38400 ; +case 57600 : +return B57600 ; +case 115200 : +return B115200 ; +case 230400 : +return B230400 ; +case 460800 : +return B460800 ; +case 500000 : +return B500000 ; +case 576000 : +return B576000 ; +case 921600 : +return B921600 ; +case 1000000 : +return B1000000 ; +case 1152000 : +return B1152000 ; +case 1500000 : +return B1500000 ; +case 2000000 : +return B2000000 ; +#ifdef B2500000 +case 2500000 : +return B2500000 ; +#endif +#ifdef B3000000 +case 3000000 : +return B3000000 ; +#endif +#ifdef B3500000 +case 3500000 : +return B3500000 ; +#endif +#ifdef B3710000 + case 3710000 + return B3710000; +#endif +#ifdef B4000000 +case 4000000 :
Quoted 8 lines
slcand.c line 176
Quoted 4 lines
slcand.c +4
-0+return B4000000 ; +#endif +default : +return B57600 ;I believe it isn't a good behaviour to return 57600 in error case. So better return a special error value like -1 and handle this error case.
Fixed
Quoted 36 lines
Quoted 36 lines
slcand.c +6
-2+ } +} + +static pid_t daemonize (const char *lockfile,char *tty,char *name) {pid_t pid, sid, parent;int lfp =-1 ;FILE * pFile; +FILE * dummyFile;char const *pidprefix ="/var/run/" ;char const *pidsuffix =".pid" ; -char pidfile[PIDFILE_LENGTH ];snprintf (pidfile,PIDFILE_LENGTH ,"%s%s-%s%s" , pidprefix,DAEMON_NAME , tty, pidsuffix);/* already a daemon */ if (getppid () ==1 ) -return ; +return 0 ;/* Create the lock file as the current user */ if (lockfile && lockfile[0])slcand.c +2
-0@@ -134,6 +214,8 @@ static void daemonize (const char *lockfile, char *tty) }/* Trap signals that we expect to receive */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler);signal (SIGCHLD , child_handler);signal (SIGUSR1 , child_handler);signal (SIGALRM, child_handler);slcand.c +0
-0@@ -152,9 +234,8 @@ static void daemonize (const char *lockfile, char *tty)
Quoted 9 lines
slcand.c
Quoted 6 lines
slcand.c +0
-0/* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
for two seconds to elapse (SIGALRM).pause()should not
return. */slcand.c +1
-1-alarm (2 ); +alarm (5 );Please correct the comment above, if you change the seconds.
Fixed. s/two/five
Quoted 38 lines
Quoted 38 lines
pause ();slcand.c +2
-2-exit (EXIT_FAILURE ); }@@ -167,7 +248,8 @@ static void daemonize (const char *lockfile, char *tty)signal (SIGTTOU ,SIG_IGN );signal (SIGTTIN ,SIG_IGN );signal (SIGHUP ,SIG_IGN );/* Ignore hangup signal */ -signal (SIGTERM ,SIG_DFL );/* Die on SIGTERM */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler);/* Change the file mode mask */ umask (0);slcand.c +1
-1@@ -182,7 +264,7 @@ static void daemonize (const char *lockfile, char *tty) } pFile =fopen (pidfile,"w" ); -if (pFile ==NULL ) +if (NULL == pFile) { syslog (LOG_ERR, "unable to create pid file %s, code=%d (%s)",pidfile, errno, strerror (errno));slcand.c +3
-3@@ -201,36 +283,88 @@ static void daemonize (const char *lockfile, char *tty) }/* Redirect standard files to /dev/null */ -freopen ("/dev/null" ,"r" , stdin); -freopen ("/dev/null" ,"w" , stdout); -freopen ("/dev/null" ,"w" , stderr); + dummyFile =freopen ("/dev/null" ,"r" , stdin); + dummyFile =freopen ("/dev/null" ,"w" , stdout); + dummyFile =freopen ("/dev/null" ,"w" , stderr);
Quoted 6 lines
slcand.c static void daemonize (const char *lockfile, char · line 292
Quoted 3 lines
slcand.c +1
-1/* Tell the parent process that we are A-okay */ -kill (parent,SIGUSR1 ); +//kill (parent, SIGUSR1); Why do you uncomment this line than remove it?
Oliver?
Quoted 59 lines
Quoted 59 lines
slcand.c +50
-1+return parent; }int main (int argc,char *argv[]) {char *tty =NULL ; -char ttypath[TTYPATH_LENGTH ];char const *devprefix ="/dev/" ;char *name =NULL ;char buf[IFNAMSIZ +1 ]; +struct termios tios; +speed_t old_ispeed; +speed_t old_ospeed; + +int opt; +int detach =1 ; +int send_open =0 ; +int send_close =0 ; +int send_read_status_flags =0 ; +char *speed =NULL ; +char *uart_speed_str =NULL ; +long int uart_speed =0 ; +char *btr =NULL ; +int run_as_daemon =1 ; +pid_t parent_pid =0 ; + + ttypath[0 ] ='\0' ; + +while ((opt =getopt (argc, argv,"ocfs:S:b:?hF" )) !=-1 ) { +switch (opt) { +case 'o' : + send_open =1 ; +break ; +case 'c' : + send_close =1 ; +break ; +case 'f' : + send_read_status_flags =1 ; +break ; +case 's' : + speed = optarg; +if (strlen (speed) >1 ) +print_usage (argv[0 ]); +break ; +case 'S' : + uart_speed_str = optarg; + errno =0 ; + uart_speed =strtol (uart_speed_str,NULL ,10 ); +if (errno) +print_usage (argv[0 ]); +break ; +case 'b' : + btr = optarg; +if (strlen (btr) >6 ) +print_usage (argv[0 ]); +break ; +case 'F' : + run_as_daemon =0 ; +break ;
Quoted 8 lines
slcand.c static void daemonize (const char *lockfile, char · line 355
Quoted 5 lines
slcand.c +5
-0+case 'h' : +case '?' : +default : +print_usage (argv[0 ]); +//exit(EXIT_SUCCESS); dito
Oliver?
Quoted 28 lines
Quoted 28 lines
slcand.c +7
-9+break ; + } + }/* Initialize the logging interface */ openlog (DAEMON_NAME ,LOG_PID ,LOG_LOCAL5 ); -/* See how we're called */ -if (argc ==2 ) { - tty = argv[1 ]; - }else if (argc ==3 ) { - tty = argv[1 ]; - name = argv[2 ]; -if (strlen (name) >IFNAMSIZ -1 ) -print_usage (argv[0 ]); - }else { +/* Parse serial device name and optional can interface name */ + tty = argv[optind]; +if (NULL == tty) {print_usage (argv[0 ]); } + name = argv[optind +1 ];/* Prepare the tty device name string */ char * pch;slcand.c +0
-0@@ -243,16 +377,69 @@ int main (int argc, char *argv[])syslog (LOG_INFO ,"starting on TTY device %s" , ttypath);
Quoted 7 lines
slcand.c int main (int argc, char *argv[]) · line 381
Quoted 4 lines
slcand.c +2
-1/* Daemonize */ -daemonize ("/var/lock/" DAEMON_NAME , tty); +if (run_as_daemon) { + parent_pid =daemonize ("/var/lock/" DAEMON_NAME , tty, name);I think
/var/lockis a perfect candidate for a define.
Oliver?
Quoted 77 lines
Quoted 77 lines
slcand.c +54
-2+ } +else { +/* Trap signals that we expect to receive */ +signal (SIGINT , child_handler); +signal (SIGTERM , child_handler); + } + +/* */ + slcand_running =1 ;/* Now we are a daemon -- do the work for which we were paid */ int fd;int ldisc =LDISC_N_SLCAN ; -if ((fd =open (ttypath,O_WRONLY |O_NOCTTY )) <0 ) { +if ((fd =open (ttypath,O_RDWR |O_NONBLOCK |O_NOCTTY )) <0 ) {syslog (LOG_NOTICE ,"failed to open TTY device %s\n" , ttypath);perror (ttypath); -exit (1 ); +exit (EXIT_FAILURE ); + } + +/* Configure baud rate */ +memset (&tios,0 ,sizeof (struct termios )); +if (tcgetattr (fd, &tios) <0 ) { + syslog (LOG_NOTICE, "failed to get attributes for TTY device %s: %s\n", ttypath, strerror(errno)); + exit (EXIT_FAILURE); + } + +/* Get old values for later restore */ + old_ispeed =cfgetispeed (&tios); + old_ospeed =cfgetospeed (&tios); + +/* Baud Rate */ +cfsetispeed (&tios,look_up_uart_speed (uart_speed)); +cfsetospeed (&tios,look_up_uart_speed (uart_speed)); + +/* apply changes */ +if (tcsetattr (fd,TCSADRAIN , &tios) <0 ) { +syslog (LOG_NOTICE ,"Cannot set attributes for device \"%s\": %s!\n" , ttypath,strerror (errno)); + } + +if (speed) { +sprintf (buf,"C\rS%s\r" , speed); +if (write (fd, buf,strlen (buf)) <0 ) { +//syslog (LO, "failed to get attributes for TTY device %s: %s\n", ttypath, strerror(errno)); + + } + } + +if (btr) { +sprintf (buf,"C\rs%s\r" , btr); +write (fd, buf,strlen (buf)); + } + +if (send_read_status_flags) { +sprintf (buf,"F\r" ); +write (fd, buf,strlen (buf)); + } + +if (send_open) { +sprintf (buf,"O\r" ); +write (fd, buf,strlen (buf));} /* set slcan like discipline on given tty */slcand.c +3
-0@@ -289,14 +476,44 @@ int main (int argc, char *argv[])close (s); } } +if (parent_pid >0 ) { +kill (parent_pid,SIGUSR1 ); + }
Quoted 16 lines
slcand.c int main (int argc, char *argv[]) · line 493
Quoted 13 lines
slcand.c +10
-2/* The Big Loop */ -while (1 ) { -sleep (60 );/* wait 60 seconds */ +while (slcand_running) { +sleep (1 );/* wait 1 second */ + } + +/* Reset line discipline */ +syslog (LOG_INFO ,"stopping on TTY device %s" , ttypath); + ldisc =N_TTY ; +if (ioctl (fd,TIOCSETD , &ldisc) <0 ) { +perror ("ioctl TIOCSETD" ); +exit (1 );Is here a
EXIT_FAILUREmissing?
Oliver?
Quoted 20 lines
Quoted 20 lines
slcand.c +17
-0+ } + +if (send_close) { +sprintf (buf,"C\r" ); +write (fd, buf,strlen (buf)); } +/* Reset old rates */ +cfsetispeed (&tios, old_ispeed); +cfsetospeed (&tios, old_ospeed); + +/* apply changes */ +if (tcsetattr (fd,TCSADRAIN , &tios) <0 ) { +syslog (LOG_NOTICE ,"Cannot set attributes for device \"%s\": %s!\n" , ttypath,strerror (errno)); + } + +/* Remove pidfile */ +if (run_as_daemon) { +unlink (pidfile);
Quoted 8 lines
Quoted 8 lines
slcand.c +3
-1+ } +/* Finish up */ syslog (LOG_NOTICE ,"terminated on %s" , ttypath);closelog (); -return 0 ; +return exit_code;}
Yegor