[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] Better error reporting afer adding advanced error messages
From: |
Bodo Eggert |
Subject: |
[PATCH 2/3] Better error reporting afer adding advanced error messages |
Date: |
Tue, 26 Sep 2023 17:09:23 +0200 |
The previous patch was a simpla patch to add advanced error messafges. It
was intentionally dumb at outputting the message to keep the changes to a
minimum.
This patch adds a more smart function to either use perror or to print the
advanced error message or sould both be of relevance - print both.
EINVAL is expected to be useless to the reader, and errno == 0 is expected
to be from an unsuccessful call to some internal function that was not
caused by an error while calling a system library function.
The advanced error 1 is still reserved for generic failures, for now it is
used for generic parse errors. I did not yet concern myself with these.
Since that code isn't meaningful to the user, it's not printed.
---
tools/parse.c | 12 +--------
tools/setfacl.c | 66 +++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 59 insertions(+), 19 deletions(-)
diff --git a/tools/parse.c b/tools/parse.c
index b4d0b7d..6f12ec6 100644
--- a/tools/parse.c
+++ b/tools/parse.c
@@ -42,7 +42,7 @@
(x)++; \
})
-/*char *advanced_errors[] = {
+char *advanced_errors[] = {
"OK",
"(generic)",
"default acl exists",
@@ -50,18 +50,8 @@
"Error while looking up user",
"Group not found",
"Error while looking up group",
-};*/
-char *advanced_errors[] = {
- "",
- "",
- " (default acl exists)",
- " (User not found)",
- " (Error while looking up user)",
- " (Group not found)",
- " (Error while looking up group)",
};
-
static int
skip_tag_name(
const char **text_p,
diff --git a/tools/setfacl.c b/tools/setfacl.c
index fe2f79d..df9695a 100644
--- a/tools/setfacl.c
+++ b/tools/setfacl.c
@@ -111,7 +111,57 @@ has_any_of_type(
}
return 0;
}
-
+
+
+// There might be a library function that's more efficient
+// for now we are required to use the reference implementation
+char *
+stpecpy(char *dst, char end[0], const char *restrict src)
+__attribute__((weak));
+
+/* This code is in the public domain,
+ it is copied from Linux man-pages 6.04 */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic error "-Wstringop-overflow=0"
+/* The end pointer is expected to be the end of the buffer
+ so it's safe to access despite being char[0] */
+char *
+stpecpy(char *dst, char end[0], const char *restrict src)
+{
+ char *p;
+
+ if (dst == NULL)
+ return NULL;
+ if (dst == end)
+ return end;
+
+ p = memccpy(dst, src, '\0', end - dst);
+ if (p != NULL)
+ return p - 1;
+
+ /* truncation detected */
+ end[-1] = '\0';
+ return end;
+}
+#pragma GCC diagnostic pop
+
+char const *
+get_advanced_error(
+ int xerrno, // errno is a macro
+ int err_ret)
+{
+ static char buf[4096];
+ char * end = buf + sizeof(buf);
+ if (err_ret <= 1)
+ return strerror(xerrno);
+ if (!xerrno || (xerrno == EINVAL))
+ return advanced_errors[err_ret];
+ char * tmp = stpecpy(buf, end, strerror(xerrno));
+ tmp = stpecpy(tmp, end, " (");
+ tmp = stpecpy(tmp, end, advanced_errors[err_ret]);
+ tmp = stpecpy(tmp, end, ")");
+ return buf;
+}
#if !POSIXLY_CORRECT
int
@@ -171,9 +221,9 @@ restore(
SEQ_PARSE_MULTI,
&lineno, NULL, &err_ret);
if (error != 0) {
- fprintf(stderr, _("%s: %s: %s%s in line %d\n"),
- progname, xquote(filename, "\n\r"),
strerror(errno),
- advanced_errors[err_ret], lineno);
+ fprintf(stderr, _("%s: %s: %s in line %d\n"),
+ progname, xquote(filename, "\n\r"),
+ get_advanced_error(errno, err_ret), lineno);
status = 1;
goto getout;
}
@@ -456,10 +506,10 @@ int main(int argc, char *argv[])
} else {
fprintf(stderr, _(
"%s: Option "
- "-%c: %s%s near "
+ "-%c: %s near "
"character %d\n"),
progname, opt,
- strerror(errno),
advanced_errors[err_ret],
+
get_advanced_error(errno, err_ret),
which+1);
}
status = 2;
@@ -534,7 +584,7 @@ int main(int argc, char *argv[])
"%s: %s%s in line "
"%d of file %s\n"),
progname,
- strerror(errno),
advanced_errors[err_ret],
+
get_advanced_error(errno, err_ret),
lineno,
xquote(optarg, "\n\r"));
} else {
@@ -542,7 +592,7 @@ int main(int argc, char *argv[])
"%s: %s%s in line "
"%d of standard "
"input\n"), progname,
- strerror(errno),
advanced_errors[err_ret],
+
get_advanced_error(errno, err_ret),
lineno);
}
status = 2;
--
2.42.0