From fd58ceb2e11ed674452bca8066e6441f16aabc46 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Thu, 17 Jan 2013 17:23:50 +0100
Subject: [PATCH] tools: added test-tdc, that writes zero-sized blocks

Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Federico Vaga <federico.vaga@gmail.com>
---
 tools/.gitignore |   2 +-
 tools/Makefile   |   1 +
 tools/test-dtc.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+), 1 deletion(-)
 create mode 100644 tools/test-dtc.c

diff --git a/tools/.gitignore b/tools/.gitignore
index 67fc23c..ebec8c3 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,3 +1,3 @@
 zio-dump
-data-to-uart
 zio-cat-file
+test-dtc
\ No newline at end of file
diff --git a/tools/Makefile b/tools/Makefile
index fe9dd11..4a2567b 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -7,6 +7,7 @@ HOSTCC ?= gcc
 
 hostprogs-y := zio-dump
 hostprogs-y += zio-cat-file
+hostprogs-y += test-dtc
 
 # The following is ugly, please forgive me by now
 user: $(hostprogs-y)
diff --git a/tools/test-dtc.c b/tools/test-dtc.c
new file mode 100644
index 0000000..b0ead77
--- /dev/null
+++ b/tools/test-dtc.c
@@ -0,0 +1,162 @@
+/*
+ * Trivial utility that reports data from ZIO input channels
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/zio.h>
+#include <linux/zio-user.h>
+
+#define FNAME "/dev/zdtc-0000-0-0-ctrl"
+
+void help(char *name)
+{
+	fprintf(stderr, "%s: Wrong number of arguments\n"
+		"Use:    \"%s [<opts>]\n", name, name);
+	fprintf(stderr,
+		"       -f <file>    default: %s\n"
+		"       -t <time>    default: \"1.5\" (see code for details)\n"
+		"       -p <period>  default: \"0\"\n"
+		"       -n <number>  default: infinite\n", FNAME);
+	exit(1);
+}
+
+/* Boring parsing separated to a separate function (same code as elsewhere) */
+static int parse_ts(char *s, struct timespec *ts)
+{
+	int i, n;
+	unsigned long nano;
+	char c;
+
+	/*
+ 	 * Hairy: if we scan "%ld%lf", the 0.009999 will become 9998 micro.
+	 * Thus, scan as integer and string, so we can count leading zeros
+	 */
+
+	nano = 0;
+	ts->tv_sec = 0;
+	ts->tv_nsec = 0;
+
+	if ( (i = sscanf(s, "%ld.%ld%c", &ts->tv_sec, &nano, &c)) == 1)
+		return 0; /* seconds only */
+	if (i == 3)
+		return -1; /* trailing crap */
+	if (i == 0)
+		if (sscanf(s, ".%ld%c", &nano, &c) != 1)
+			return -1; /* leading or trailing crap */
+
+	s = strchr(s, '.') + 1;
+	n = strlen(s);
+	if (n > 9)
+		return -1; /* too many decimals */
+	while (n < 9) {
+		nano *= 10;
+		n++;
+	}
+	ts->tv_nsec = nano;
+	return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+	struct zio_control ctrl = {0,};
+	char *fname = FNAME;
+	int verbose = 0;
+	char *t = NULL, *p = NULL;
+	int i, fd, n = -1;
+	struct timespec ts = {1, 5};
+	struct timespec period = {0, 0};
+
+	/* -f <filename> -t <[+][secs].frac> -p <.frac> -v */
+	while ((i = getopt (argc, argv, "f:t:p:n:v")) != -1) {
+		switch(i) {
+		case 'f':
+			fname = optarg;
+			break;
+		case 't':
+			t = optarg;
+			break;
+		case 'p':
+			p = optarg;
+			break;
+		case 'n':
+			n = atoi(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		default:
+			help(argv[0]);
+		}
+	}
+	if (!n)
+		help(argv[0]);
+
+	if (t) {
+		char *t2 = t;
+
+		if (t[0] == '+')
+			t2++;
+		if (parse_ts(t2, &ts) < 0) {
+			fprintf(stderr, "%s: can't parse time \"%s\"\n",
+				argv[0], t);
+			exit(1);
+		}
+		if (t[0] == '+')
+			ts.tv_sec += time(NULL);
+	}
+	if (p) {
+		if (parse_ts(p, &period) < 0) {
+			fprintf(stderr, "%s: can't parse period \"%s\"\n",
+				argv[0], p);
+			exit(1);
+		}
+	}
+
+	fd = open(fname, O_WRONLY);
+	if (fd < 0) {
+		fprintf(stderr, "%s: %s: %s\n", argv[0], fname,
+			strerror(errno));
+		exit(1);
+	}
+
+	ctrl.major_version = ZIO_MAJOR_VERSION;
+	ctrl.minor_version = ZIO_MINOR_VERSION;
+	if (verbose) {
+		printf("  time: %9li.%09li\n", ts.tv_sec, ts.tv_nsec);
+		printf("period: %9li.%09li\n", period.tv_sec, period.tv_nsec);
+	}
+	while (n != 0) {
+		ctrl.tstamp.secs = ts.tv_sec;
+		ctrl.tstamp.ticks = ts.tv_nsec;
+		if (verbose)
+			printf("%9li.%09li", ts.tv_sec, ts.tv_nsec);
+		i = write(fd, &ctrl, sizeof(ctrl));
+		if (i != sizeof(ctrl)) {
+			fprintf(stderr, "%s: %s: write error (%i bytes, %s)\n",
+				argv[0], fname, i, strerror(errno));
+			exit(1);
+		}
+		if (verbose)
+			printf("\n");
+		ts.tv_nsec += period.tv_nsec;
+		if (ts.tv_nsec >= 1000 * 1000 * 1000) {
+			ts.tv_nsec -= 1000 * 1000 * 1000;
+			ts.tv_sec++;
+		}
+		ts.tv_sec += period.tv_sec;
+		if (n > 0)
+			n--;
+	}
+	exit(0);
+}
-- 
GitLab