diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2006-03-22 10:37:09 +0000 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2006-03-22 10:37:09 +0000 |
commit | 7050cce01dce7c00ae531b871c6ebd4e77d13d24 (patch) | |
tree | e5bb8178fdeec489615c20acd0584f4b4e2a024e | |
parent | 4e5c20dab63cb97c30ea8279fc145330171131e3 (diff) | |
download | canutils-7050cce01dce7c00ae531b871c6ebd4e77d13d24.tar.gz canutils-7050cce01dce7c00ae531b871c6ebd4e77d13d24.tar.xz |
* candump.c:
added possibility to dump into fifo
git-svn-id: https://iocaste.extern.pengutronix.de/svn/canutils/trunks/canutils-1.1-trunk@60 5fd5a299-6ef2-0310-aa18-8b01d7c39d8c
-rw-r--r-- | src/candump.c | 157 |
1 files changed, 100 insertions, 57 deletions
diff --git a/src/candump.c b/src/candump.c index bf1514a..78acdbf 100644 --- a/src/candump.c +++ b/src/candump.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -30,14 +31,16 @@ static void print_usage(char *prg) { fprintf(stderr, "Usage: %s <can-interface> [Options]\n" "Options:\n" - " -f, --family=FAMILY protocol family (default PF_CAN = %d)\n" - " -t, --type=TYPE socket type, see man 2 socket (default SOCK_RAW = %d)\n" - " -p, --protocol=PROTO CAN protocol (default CAN_PROTO_RAW = %d)\n" + " -f, --family=FAMILY\t" "protocol family (default PF_CAN = %d)\n" + " -t, --type=TYPE\t" "socket type, see man 2 socket (default SOCK_RAW = %d)\n" + " -p, --protocol=PROTO\t" "CAN protocol (default CAN_PROTO_RAW = %d)\n" " --filter=id:mask[:id:mask]...\n" - " apply filter\n" - " -h, --help this help\n" - " --version print version information and exit\n", - prg, PF_CAN, SOCK_RAW, CAN_PROTO_RAW); + "\t\t\t" "apply filter\n" + " -h, --help\t\t" "this help\n" + " -o <filename>\t\t" "output into filename\n" + " -d\t\t\t" "daemonize\n" + " --version\t\t" "print version information and exit\n", + prg, PF_CAN, SOCK_RAW, CAN_PROTO_RAW); } static void sigterm(int signo) @@ -62,17 +65,24 @@ int add_filter(u_int32_t id, u_int32_t mask) return 0; } +#define BUF_SIZ (255) + int main(int argc, char **argv) { int family = PF_CAN, type = SOCK_RAW, proto = CAN_PROTO_RAW; - int opt; + int opt, optdaemon = 0; struct sockaddr_can addr; struct can_frame frame; int nbytes, i; struct ifreq ifr; char *ptr; + char *optout = NULL; u_int32_t id, mask; + FILE *out = stdout; + char buf[BUF_SIZ]; + int n = 0, err; + signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sigterm); signal(SIGHUP, sigterm); @@ -86,60 +96,68 @@ int main(int argc, char **argv) { 0, 0, 0, 0}, }; - while ((opt = getopt_long(argc, argv, "f:t:p:", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "f:t:p:o:d", long_options, NULL)) != -1) { switch (opt) { - case 'h': - print_usage(basename(argv[0])); - exit(0); - - case 'f': - family = strtoul(optarg, NULL, 0); - break; - - case 't': - type = strtoul(optarg, NULL, 0); - break; - - case 'p': - proto = strtoul(optarg, NULL, 0); - break; - - case FILTER_OPTION: - ptr = optarg; - while(1) { - id = strtoul(ptr, NULL, 0); - ptr = strchr(ptr, ':'); - if(!ptr) { - fprintf(stderr, "filter must be applied in the form id:mask[:id:mask]...\n"); - exit(1); - } - ptr++; - mask = strtoul(ptr, NULL, 0); - ptr = strchr(ptr, ':'); - add_filter(id,mask); - if(!ptr) - break; - ptr++; + case 'd': + optdaemon++; + break; + + case 'h': + print_usage(basename(argv[0])); + exit(0); + + case 'f': + family = strtoul(optarg, NULL, 0); + break; + + case 't': + type = strtoul(optarg, NULL, 0); + break; + + case 'p': + proto = strtoul(optarg, NULL, 0); + break; + + case 'o': + optout = optarg; + break; + + case FILTER_OPTION: + ptr = optarg; + while(1) { + id = strtoul(ptr, NULL, 0); + ptr = strchr(ptr, ':'); + if(!ptr) { + fprintf(stderr, "filter must be applied in the form id:mask[:id:mask]...\n"); + exit(1); } - break; + ptr++; + mask = strtoul(ptr, NULL, 0); + ptr = strchr(ptr, ':'); + add_filter(id,mask); + if(!ptr) + break; + ptr++; + } + break; - case VERSION_OPTION: - printf("candump %s\n",VERSION); - exit(0); + case VERSION_OPTION: + printf("candump %s\n",VERSION); + exit(0); - default: - fprintf(stderr, "Unknown option %c\n", opt); - break; + default: + fprintf(stderr, "Unknown option %c\n", opt); + break; } } if (optind == argc) { print_usage(basename(argv[0])); - exit(0); + exit (EXIT_SUCCESS); } - printf("interface = %s, family = %d, type = %d, proto = %d\n", - argv[optind], family, type, proto); + fprintf(out, "interface = %s, family = %d, type = %d, proto = %d\n", + argv[optind], family, type, proto); if ((s = socket(family, type, proto)) < 0) { perror("socket"); return 1; @@ -163,23 +181,48 @@ int main(int argc, char **argv) } } + if (optout) { + out = fopen(optout, "a"); + if (!out) { + perror("fopen"); + exit (EXIT_FAILURE); + } + } + + if (optdaemon) + daemon(1, 0); + while (running) { if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { perror("read"); return 1; } else { if (frame.can_id & CAN_FLAG_EXTENDED) - printf("<0x%08x> ", frame.can_id & CAN_ID_EXT_MASK); + n = snprintf(buf, BUF_SIZ, "<0x%08x> ", frame.can_id & CAN_ID_EXT_MASK); else - printf("<0x%03x> ", frame.can_id & CAN_ID_STD_MASK); + n = snprintf(buf, BUF_SIZ, "<0x%03x> ", frame.can_id & CAN_ID_STD_MASK); - printf("[%d] ", frame.can_dlc); + n += snprintf(buf + n, BUF_SIZ - n, "[%d] ", frame.can_dlc); for (i = 0; i < frame.can_dlc; i++) { - printf("%02x ", frame.payload.data_u8[i]); + n += snprintf(buf + n, BUF_SIZ - n, "%02x ", frame.payload.data_u8[i]); } if (frame.can_id & CAN_FLAG_RTR) - printf("remote request"); - printf("\n"); + n += snprintf(buf + n, BUF_SIZ - n, "remote request"); + + fprintf(out, "%s\n", buf); + + do { + err = fflush(out); + if (err == -1 && errno == EPIPE) { + err = -EPIPE; + fclose(out); + out = fopen(optout, "a"); + if (!out) + exit (EXIT_FAILURE); + } + } while (err == -EPIPE); + + n = 0; } } |