"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: capsicum work: add fd field to got_repository, change got_packidx
To:
"Todd C. Miller" <millert@openbsd.org>
Cc:
Yang Zhong <yzhong@freebsdfoundation.org>, gameoftrees@openbsd.org
Date:
Tue, 15 Dec 2020 23:27:55 +0100

Download raw body.

Thread
On Tue, Dec 15, 2020 at 02:16:33PM -0700, Todd C. Miller wrote:
> On Tue, 15 Dec 2020 22:02:46 +0100, Stefan Sperling wrote:
> 
> > I'm afraid we'll end up with even more got_error functions to cover
> > combinations of the number of path components (separeated by /) and
> > error message components (separated by :).
> 
> Why not just add a variant that takes a format string and a variable
> number of args?  It will end up in snprintf (well, vsnprintf) either
> way.  You could even use that to replaces calls to got_error_from_errno2()
> and got_error_from_errno3() if desired.

Sure. It seems like we'll more flexibility when building error messages
and this is probably the easiest way to go about it.

This adds an errno-specific interface, meaning it always appends the
result of strerror(3) to the provided format string.

If this interface works for Yang, then I will also add a non-errno-specific
version which can be used in cases where an error is generated in the
application rather than the system.

I'm showing the got.c to demonstrate usage of this interface.
I don't intend to commit that change just yet.
I've tested this path with: got log -r /nonexistent/path

ok?

diff 25a0dd03b5dfa4a2175793af9cb7c24dd3f58d45 944cd0e367e9dbd45873211ad20adc1e2c4a4217
blob - 6d427879bfb75db1dd06c1c4b0eb326ddd18ffc0
blob + 49901519c6a71ffc6eb20ba19d48afac3b11a431
--- got/got.c
+++ got/got.c
@@ -3741,8 +3741,8 @@ cmd_log(int argc, char *argv[])
 		case 'r':
 			repo_path = realpath(optarg, NULL);
 			if (repo_path == NULL)
-				return got_error_from_errno2("realpath",
-				    optarg);
+				return got_error_from_errno_fmt("%s: %s",
+				   "realpath", optarg);
 			got_path_strip_trailing_slashes(repo_path);
 			break;
 		case 'R':
blob - 5fa8ffa0d2de4c2d61942eb2eed66a240149f6d0
blob + d3127f6f9acf465b17b825b7deb3d42b7a42fe7d
--- include/got_error.h
+++ include/got_error.h
@@ -336,6 +336,14 @@ const struct got_error *got_error_from_errno3(const ch
     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
blob - 6cbb7ca6b8a72218dbc5725fed24856910329b8f
blob + 2517e876adafe5fb3b9f9cddb3e16bb8242e9f6b
--- lib/error.c
+++ 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 *
 }
 
 const struct got_error *
+got_error_from_errno_fmt(const char *fmt, ...)
+{
+	static struct got_error err;
+	static char buf[PATH_MAX * 4];
+	static char err_msg[PATH_MAX * 4 + 64];
+	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;