Commit 4cc6a5a5fa3d5a5351d59385e614a0a78d167987

Stefan Sperling 2020-12-15T22:42:20

add got_error_from_errno_fmt() for more flexibility in error messages suggested by and ok millert

diff --git a/include/got_error.h b/include/got_error.h
index 5fa8ffa..d3127f6 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -336,6 +336,14 @@ const struct got_error *got_error_from_errno3(const char *, const char *,
     const char *);
 
 /*
+ * Get a statically allocated error object with code GOT_ERR_ERRNO
+ * and an error message obtained from strerror(3), prefixed with a
+ * string built with vsnprintf(3) from the provided format string
+ * and the variable-length list of additional arguments.
+ */
+const struct got_error *got_error_from_errno_fmt(const char *, ...);
+
+/*
  * Set errno to the specified error code and return a statically
  * allocated error object with code GOT_ERR_ERRNO and an error
  * message obtained from strerror(3), optionally prefixed with a
diff --git a/lib/error.c b/lib/error.c
index 6cbb7ca..f8cf59b 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -111,6 +112,25 @@ got_error_from_errno3(const char *prefix, const char *prefix2,
 }
 
 const struct got_error *
+got_error_from_errno_fmt(const char *fmt, ...)
+{
+	static struct got_error err;
+	static char err_msg[PATH_MAX * 4 + 64];
+	char buf[PATH_MAX * 4];
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	va_end(ap);
+
+	snprintf(err_msg, sizeof(err_msg), "%s: %s", buf, strerror(errno));
+
+	err.code = GOT_ERR_ERRNO;
+	err.msg = err_msg;
+	return &err;
+}
+
+const struct got_error *
 got_error_set_errno(int code, const char *prefix)
 {
 	errno = code;