about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-11-14 17:10:28 -0500
committerJune McEnroe <june@causal.agency>2019-11-14 17:10:28 -0500
commit474de83b4dab1668b83c133435e5896ee002b6af (patch)
tree5a02a34810d1dccaf6b56ea5b7770421a551e1b3
parentRemove server-time filter TODO (diff)
downloadpounce-474de83b4dab1668b83c133435e5896ee002b6af.tar.gz
pounce-474de83b4dab1668b83c133435e5896ee002b6af.zip
Use struct timeval for sub-second precision
-rw-r--r--bounce.h6
-rw-r--r--client.c14
-rw-r--r--ring.c18
3 files changed, 21 insertions, 17 deletions
diff --git a/bounce.h b/bounce.h
index 7bf830b..5afce01 100644
--- a/bounce.h
+++ b/bounce.h
@@ -18,7 +18,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
+#include <sys/time.h>
 #include <tls.h>
 
 #include "compat.h"
@@ -116,8 +116,8 @@ void ringAlloc(size_t len);
 void ringProduce(const char *line);
 size_t ringConsumer(const char *name);
 size_t ringDiff(size_t consumer);
-const char *ringPeek(time_t *time, size_t consumer);
-const char *ringConsume(time_t *time, size_t consumer);
+const char *ringPeek(struct timeval *time, size_t consumer);
+const char *ringConsume(struct timeval *time, size_t consumer);
 void ringInfo(void);
 int ringSave(FILE *file);
 void ringLoad(FILE *file);
diff --git a/client.c b/client.c
index de3f087..3dce5e9 100644
--- a/client.c
+++ b/client.c
@@ -19,6 +19,7 @@
 #include <regex.h>
 #include <stdarg.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -394,7 +395,7 @@ static Filter *Filters[] = {
 };
 
 void clientConsume(struct Client *client) {
-	time_t time;
+	struct timeval time;
 	const char *line = ringPeek(&time, client->consumer);
 	if (!line) return;
 
@@ -409,10 +410,13 @@ void clientConsume(struct Client *client) {
 	}
 
 	if (client->caps & CapServerTime) {
-		char ts[sizeof("YYYY-MM-DDThh:mm:ss.sssZ")];
-		struct tm *tm = gmtime(&time);
-		strftime(ts, sizeof(ts), "%FT%T.000Z", tm);
-		clientFormat(client, "@time=%s %s\r\n", ts, line);
+		char ts[sizeof("YYYY-MM-DDThh:mm:ss")];
+		struct tm *tm = gmtime(&time.tv_sec);
+		strftime(ts, sizeof(ts), "%FT%T", tm);
+		clientFormat(
+			client, "@time=%s.%03jdZ %s\r\n",
+			ts, (intmax_t)(time.tv_usec / 1000), line
+		);
 	} else {
 		clientFormat(client, "%s\r\n", line);
 	}
diff --git a/ring.c b/ring.c
index f0e7a05..3bd177d 100644
--- a/ring.c
+++ b/ring.c
@@ -18,15 +18,15 @@
 #include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/time.h>
 #include <sysexits.h>
-#include <time.h>
 
 #include "bounce.h"
 
 static struct {
 	size_t len;
 	char **lines;
-	time_t *times;
+	struct timeval *times;
 } ring;
 
 void ringAlloc(size_t len) {
@@ -45,7 +45,7 @@ size_t producer;
 void ringProduce(const char *line) {
 	size_t i = producer++ & (ring.len - 1);
 	if (ring.lines[i]) free(ring.lines[i]);
-	ring.times[i] = time(NULL);
+	gettimeofday(&ring.times[i], NULL);
 	ring.lines[i] = strdup(line);
 	if (!ring.lines[i]) err(EX_OSERR, "strdup");
 }
@@ -86,7 +86,7 @@ size_t ringDiff(size_t consumer) {
 	return producer - consumers.ptr[consumer].pos;
 }
 
-const char *ringPeek(time_t *time, size_t consumer) {
+const char *ringPeek(struct timeval *time, size_t consumer) {
 	if (!ringDiff(consumer)) return NULL;
 	if (ringDiff(consumer) > ring.len) {
 		warnx(
@@ -101,7 +101,7 @@ const char *ringPeek(time_t *time, size_t consumer) {
 	return ring.lines[i];
 }
 
-const char *ringConsume(time_t *time, size_t consumer) {
+const char *ringConsume(struct timeval *time, size_t consumer) {
 	const char *line = ringPeek(time, consumer);
 	if (line) consumers.ptr[consumer].pos++;
 	return line;
@@ -119,8 +119,8 @@ void ringInfo(void) {
 }
 
 static const size_t FileVersion[] = {
-	0x0165636E756F70,
-	0x0265636E756F70,
+	0x0165636E756F70, // no ring size
+	0x0265636E756F70, // time_t only
 };
 
 static int writeSize(FILE *file, size_t value) {
@@ -143,7 +143,7 @@ int ringSave(FILE *file) {
 		if (writeSize(file, consumers.ptr[i].pos)) return -1;
 	}
 	for (size_t i = 0; i < ring.len; ++i) {
-		if (writeTime(file, ring.times[i])) return -1;
+		if (writeTime(file, ring.times[i].tv_sec)) return -1;
 	}
 	for (size_t i = 0; i < ring.len; ++i) {
 		if (!ring.lines[i]) break;
@@ -196,7 +196,7 @@ void ringLoad(FILE *file) {
 	}
 
 	for (size_t i = 0; i < saveLen; ++i) {
-		readTime(file, &ring.times[i]);
+		readTime(file, &ring.times[i].tv_sec);
 	}
 	for (size_t i = 0; i < saveLen; ++i) {
 		readString(file, &buf, &cap);