r4227 - developers/werner/neocon
werner at sita.openmoko.org
werner at sita.openmoko.org
Wed Mar 19 22:05:45 CET 2008
Author: werner
Date: 2008-03-19 22:05:41 +0100 (Wed, 19 Mar 2008)
New Revision: 4227
Modified:
developers/werner/neocon/README
developers/werner/neocon/neocon.c
Log:
- neocon.c: new option "-l logfile" to log to a file
- neocon.c: new option "-a" to append to the log file instead of overwriting it
- neocon.c: new option "-T" to prepend a timestamp to each line logged
- neocon.c: new option "-e escape" to change the escape character
- README: described new options and documented remaining known issue
Modified: developers/werner/neocon/README
===================================================================
--- developers/werner/neocon/README 2008-03-19 19:32:03 UTC (rev 4226)
+++ developers/werner/neocon/README 2008-03-19 21:05:41 UTC (rev 4227)
@@ -11,3 +11,21 @@
The option -t delay_ms throttles keyboard input to a rate of
one character every "delay_ms" milliseconds. This can be used to
prevent buffer overruns on the remote end.
+
+"neocon" can log to a file with the option "-l logfile". Non-ASCII
+and non-printable characters are converted to hash signs (#). To
+append to an existing logfile, add the option "-a". To add a
+timestamp before each line, use the option "-T".
+
+To leave neocon, type "~.". The escape character (~) can be changed
+with the option "-e escape".
+
+
+Known issues
+------------
+
+Sometimes, the USB stack locks up without neocon ever noticing.
+To reproduce:
+
+- neocon with ttyACM* to u-boot
+- in u-boot, reset
Modified: developers/werner/neocon/neocon.c
===================================================================
--- developers/werner/neocon/neocon.c 2008-03-19 19:32:03 UTC (rev 4226)
+++ developers/werner/neocon/neocon.c 2008-03-19 21:05:41 UTC (rev 4227)
@@ -1,7 +1,7 @@
/*
* neocon.c - An interface for changing tty devices
*
- * Copyright (C) 2007 by OpenMoko, Inc.
+ * Copyright (C) 2007, 2008 by OpenMoko, Inc.
* Written by Werner Almesberger <werner at openmoko.org>
* All Rights Reserved
*
@@ -28,12 +28,20 @@
#include <string.h>
#include <termios.h>
#include <fcntl.h>
+#include <assert.h>
+#include <sys/time.h>
#include <sys/select.h>
+
+#define MAX_BUF 2048
+
static char *const *ttys;
static int num_ttys;
static speed_t speed = B115200;
static struct termios console, tty;
+static FILE *log = NULL;
+static int timestamp = 0;
+static char escape = '~';
static struct bps {
@@ -127,7 +135,7 @@
for (i = 0; i != len; i++)
switch (state) {
case 0:
- if (s[i] == '~')
+ if (s[i] == escape)
state++;
else
state = 0;
@@ -141,16 +149,83 @@
}
-static int copy(int in, int out, int scan_escape, int single)
+static int write_log(const char *buf, ssize_t len)
{
- char buffer[2048];
+ size_t wrote;
+
+ wrote = fwrite(buf, 1, len, log);
+ if (wrote == len)
+ return 1;
+ fprintf(stderr, "write failed. closing log file.\n");
+ fclose(log);
+ log = NULL;
+ return 0;
+}
+
+
+static int add_timestamp(void)
+{
+ struct timeval tv;
+ char buf[40]; /* be generous */
+ int len;
+
+ if (gettimeofday(&tv, NULL) < 0) {
+ perror("gettimeofday");
+ exit(1);
+ }
+ len = sprintf(buf, "%lu.%06lu ",
+ (unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec);
+ return write_log(buf, len);
+}
+
+
+static void do_log(const char *buf, ssize_t len)
+{
+ static int nl = 1; /* we're at the beginning of a new line */
+ char tmp[MAX_BUF];
+ const char *from;
+ char *to;
+
+ assert(len <= MAX_BUF);
+ from = buf;
+ to = tmp;
+ while (from != buf+len) {
+ if (*from == '\r') {
+ from++;
+ continue;
+ }
+ if (nl && timestamp)
+ if (!add_timestamp())
+ return;
+ nl = 0;
+ if (*from == '\n') {
+ *to++ = *from++;
+ if (!write_log(tmp, to-tmp))
+ return;
+ to = tmp;
+ nl = 1;
+ continue;
+ }
+ *to++ = *from < ' ' || *from > '~' ? '#' : *from;
+ from++;
+ }
+ write_log(tmp, to-tmp);
+}
+
+
+static int copy(int in, int out, int from_user, int single)
+{
+ char buffer[MAX_BUF];
ssize_t got, wrote, pos;
got = read(in, buffer, single ? 1 : sizeof(buffer));
if (got < 0)
return 0;
- if (scan_escape)
+ if (from_user)
scan(buffer, got);
+ else
+ if (log)
+ do_log(buffer, got);
for (pos = 0; pos != got; pos += wrote) {
wrote = write(out, buffer+pos, got-pos);
if (wrote < 0)
@@ -187,7 +262,15 @@
static void usage(const char *name)
{
- fprintf(stderr, "usage: %s [-b bps] [-t delay_ms] tty ...\n", name);
+ fprintf(stderr,
+"usage: %s [-b bps] [-e escape] [-l logfile [-a] [-T]] [-t delay_ms] tty ...\n\n"
+" -a append to the log file if it already exists\n"
+" -b bps set the TTY to the specified bit rate\n"
+" -e escape set the escape character (default: ~)\n"
+" -l logfile log all output to the specified file\n"
+" -t delay_ms wait the specified amount of time between input characters\n"
+" -T add timestamps to the log file\n"
+ , name);
exit(1);
}
@@ -197,28 +280,53 @@
char *end;
int c, bps;
int fd = -1;
+ int append = 0;
+ const char *logfile = NULL;
int throttle_us = 0;
int throttle = 0;
- while ((c = getopt(argc, argv, "b:t:")) != EOF)
+ while ((c = getopt(argc, argv, "ab:e:l:t:T")) != EOF)
switch (c) {
+ case 'a':
+ append = 1;
+ break;
case 'b':
bps = strtoul(optarg, &end, 0);
if (*end)
usage(*argv);
speed = bps_to_speed(bps);
break;
+ case 'e':
+ if (strlen(optarg) != 1)
+ usage(*argv);
+ escape = *optarg;
+ break;
+ case 'l':
+ logfile = optarg;
+ break;
case 't':
throttle_us = strtoul(optarg, &end, 0)*1000;
if (*end)
usage(*argv);
break;
+ case 'T':
+ timestamp = 1;
+ break;
default:
usage(*argv);
}
num_ttys = argc-optind;
ttys = argv+optind;
+ if (logfile) {
+ log = fopen(logfile, append ? "a" : "w");
+ if (!log) {
+ perror(logfile);
+ exit(1);
+ }
+ setlinebuf(log);
+ }
+
make_raw(0, &console);
atexit(cleanup);
while (1) {
More information about the commitlog
mailing list