tttm

git clone https://orangeshoelaces.net/git/tttm.git

aab34d5663d8c96c357e82f92d2b994e712f5302

Author: Vasily Kolobkov on 08/02/2017

Committer: Vasily Kolobkov on 08/02/2017

Handle errors in BSD's <err.h> vein

Stats

README    |  5 +-
errors.c  | 62 ++++++++
errors.h  |  7 +
pshades.c |  8 +-
tttm.c    |  6 +-
5 files changed, 82 insertions(+), 6 deletions(-)

Patch

diff --git a/README b/README
index e577c5b..89a1727 100644
--- a/README
+++ b/README
@@ -6,9 +6,8 @@ from server afterwards.
 
 See manual for details.
 
-Tested to work on OpenBSD. Likely to behave just as fine on other
-BSDs, while building on Linux require some effort (factoring error
-handling BSD-isms out).
+Works on OpenBSD. Likely to behave just as fine on other BSDs,
+Linuxes and other POSIX-friendly operating systems.
 
 Needs a decent C compiler (uses some of C11 feats) with standard
 library.
diff --git a/errors.c b/errors.c
index 20992f6..948dbbc 100644
--- a/errors.c
+++ b/errors.c
@@ -1,3 +1,10 @@
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "errors.h"
 
 const char *errmsgs[] = {
@@ -17,3 +24,58 @@ const char *errmsgs[] = {
 	[TE_IN]         = "input error",
 	[TE_OUT]        = "output error",
 };
+
+static void vwarn(char *, va_list);
+static void vwarnx(char *, va_list);
+
+void warn(char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vwarn(fmt, ap);
+	va_end(ap);
+}
+
+void warnx(char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vwarnx(fmt, ap);
+	va_end(ap);
+}
+
+void err(int status, char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vwarn(fmt, ap);
+	va_end(ap);
+	exit(status);
+}
+
+void errx(int status, char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vwarnx(fmt, ap);
+	va_end(ap);
+	exit(status);
+}
+
+void vwarn(char *fmt, va_list ap)
+{
+	dprintf(STDERR_FILENO, fmt ? "%s: " : "%s", prog);
+	if (fmt) vdprintf(STDERR_FILENO, fmt, ap);
+	dprintf(STDERR_FILENO, ": %s\n", strerror(errno));
+}
+
+void vwarnx(char *fmt, va_list ap)
+{
+	dprintf(STDERR_FILENO, fmt ? "%s: " : "%s", prog);
+	if (fmt) vdprintf(STDERR_FILENO, fmt, ap);
+	dprintf(STDERR_FILENO, "\n");
+}
diff --git a/errors.h b/errors.h
index 98385ec..6203a0c 100644
--- a/errors.h
+++ b/errors.h
@@ -24,3 +24,10 @@ enum {
 };
 
 extern const char *errmsgs[];
+
+extern char *prog;
+
+void warn(char *, ...);
+void warnx(char *, ...);
+void err(int, char *, ...);
+void errx(int, char *, ...);
diff --git a/pshades.c b/pshades.c
index 796dc8b..b7ec795 100644
--- a/pshades.c
+++ b/pshades.c
@@ -1,6 +1,5 @@
-#include <err.h>
-#include <errno.h>
 #include <fcntl.h>
+#include <libgen.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -47,6 +46,8 @@ char *literals[] = {
 
 void ptprint(union parnode *, char *, size_t);
 
+char *prog;
+
 int
 main(int argc, char **argv)
 {
@@ -55,12 +56,15 @@ main(int argc, char **argv)
 	size_t cap, len, parsed;
 	union parnode pt[1024];
 
+	prog = basename(argv[0]);
+
 	#ifdef __OpenBSD__
 	if(pledge("stdio proc", 0) == -1) {
 		err(1, "pledge");
 	}
 	#endif
 
+	ln = 0;
 	cap = len = parsed = 0;
 	if ((e = par_parseln(STDIN_FILENO, &ln, &cap, &len, &parsed, pt, LEN(pt))))
 		errx(1, "error parsing input: %s",  errmsgs[e]);
diff --git a/tttm.c b/tttm.c
index e24c2a1..d7b0ff3 100644
--- a/tttm.c
+++ b/tttm.c
@@ -1,6 +1,6 @@
-#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libgen.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -32,6 +32,8 @@ static void	usage(void);
 static char	*userkey = "IMAP_USER";
 static char	*passkey = "IMAP_PASS";
 
+char *prog;
+
 int
 main(int argc, char **argv)
 {
@@ -42,6 +44,8 @@ main(int argc, char **argv)
 	struct msgd bag[BATCHSZ], *m, *bend;
 	long sysvar;
 
+	prog = basename(argv[0]);
+
 	#ifdef __OpenBSD__
 	if(pledge("stdio proc exec", 0) == -1) {
 		err(1, "pledge");