--- /dev/null	2014-01-16 12:45:53.000000000 +0100
+++ err.h	2014-01-16 12:14:10.000000000 +0100
@@ -0,0 +1,39 @@
+
+#ifndef	_ERR_H
+#define	_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+#ifndef _Noreturn
+# define __ERR_H_DEFINED_NORETURN
+# define _Noreturn
+#endif
+
+/* Program exit and warning calls */
+_Noreturn void	err(int, const char *, ...);
+_Noreturn void	verr(int, const char *, va_list);
+_Noreturn void	errc(int, int, const char *, ...);
+_Noreturn void	verrc(int, int, const char *, va_list);
+_Noreturn void	errx(int, const char *, ...);
+_Noreturn void	verrx(int, const char *, va_list);
+
+void		warn(const char *, ...);
+void		vwarn(const char *, va_list);
+void		warnc(int, const char *, ...);
+void		vwarnc(int, const char *, va_list);
+void		warnx(const char *, ...);
+void		vwarnx(const char *, va_list);
+
+#ifdef __ERR_H_DEFINED_NORETURN
+# undef _Noreturn
+# undef __ERR_H_DEFINED_NORETURN
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ERR_H */
--- /dev/null	2014-01-16 12:45:57.000000000 +0100
+++ err.c	2014-01-16 12:44:52.000000000 +0100
@@ -0,0 +1,174 @@
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* Thread-safe locked with multiple I/Os, or a single output?
+ * Is used as the stack buffer size if defined */
+/*#define __PREPARE_STACK_BUFFER	1024*/
+
+/* Get the program name as a const char* */
+#define __PROGRAM_NAME()	getprogname()
+
+/* The shared workhorse */
+static void	_errwarn(FILE *fp, int doerr, int code, const char *fmt,
+			va_list args);
+
+static void
+_errwarn(FILE *fp, int doerr, int code, const char *fmt, va_list args)
+{
+#ifdef __PREPARE_STACK_BUFFER
+	char buffer[__PREPARE_STACK_BUFFER];
+	size_t len;
+	int i;
+
+	i = snprintf(buffer, sizeof buffer, "%s: ", __PROGRAM_NAME());
+	if (i < 0)
+		goto jleave;
+	len = i;
+	if (len >= sizeof buffer)
+		goto jprint;
+
+	if (fmt != NULL) {
+		i = vsnprintf(buffer + len, sizeof(buffer) - len, fmt, args);
+		if (i < 0)
+			goto jleave;
+		len += i;
+		if (len >= sizeof buffer)
+			goto jprint;
+	}
+
+	if (doerr) {
+		i = snprintf(buffer + len, sizeof(buffer) - len, ": %s",
+			strerror(code));
+		if (i < 0)
+			goto jleave;
+		len += i;
+	}
+jprint:
+	if (len >= sizeof buffer)
+		len = sizeof(buffer) - 2;
+	buffer[len++] = '\n';
+	buffer[len] = '\0';
+	fputs(buffer, fp);
+	fflush(fp);
+jleave:
+	;
+
+#else /* __PREPARE_STACK_BUFFER */
+	flockfile(fp);
+	fprintf(fp, "%s: ", __PROGRAM_NAME());
+	if (fmt != NULL)
+		vfprintf(fp, fmt, args);
+	if (doerr)
+		fprintf(fp, ": %s", strerror(code));
+	fputc('\n', fp);
+	fflush(fp);
+	funlockfile(fp);
+#endif
+}
+
+void
+err(int status, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 1, errno, fmt, args);
+	va_end(args);
+	exit(status);
+}
+
+void
+verr(int status, const char *fmt, va_list args)
+{
+	_errwarn(stderr, 1, errno, fmt, args);
+	exit(status);
+}
+
+void
+errc(int status, int code, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 1, code, fmt, args);
+	va_end(args);
+	exit(status);
+}
+
+void
+verrc(int status, int code, const char *fmt, va_list args)
+{
+	_errwarn(stderr, 1, code, fmt, args);
+	exit(status);
+}
+
+void
+errx(int status, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 0, 0, fmt, args);
+	va_end(args);
+	exit(status);
+}
+
+void
+verrx(int status, const char *fmt, va_list args)
+{
+	_errwarn(stderr, 0, 0, fmt, args);
+	exit(status);
+}
+
+void
+warn(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 1, errno, fmt, args);
+	va_end(args);
+}
+
+void
+vwarn(const char *fmt, va_list args)
+{
+	_errwarn(stderr, 1, errno, fmt, args);
+}
+
+void
+warnc(int code, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 1, code, fmt, args);
+	va_end(args);
+}
+
+void
+vwarnc(int code, const char *fmt, va_list args)
+{
+	_errwarn(stderr, 1, code, fmt, args);
+}
+
+void
+warnx(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	_errwarn(stderr, 0, 0, fmt, args);
+	va_end(args);
+}
+
+void
+vwarnx(const char *fmt, va_list args)
+{
+	_errwarn(stderr, 0, 0, fmt, args);
+}
