summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-12-03 22:46:10 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-12-03 22:46:10 +0000
commit61320c44c1c09a1e9b455771437c94174108739c (patch)
treed7cdbc3b40eec96ded0ac715ef61830c49211770 /Src/utils.c
parent9794b454777867201e242c425b4fd9629c669fee (diff)
downloadzsh-61320c44c1c09a1e9b455771437c94174108739c.tar.gz
zsh-61320c44c1c09a1e9b455771437c94174108739c.zip
24148: attempt to use strerror_r() to make errors in signal handle safer
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/Src/utils.c b/Src/utils.c
index f9e658c0f..7c22a277f 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -255,6 +255,12 @@ zerrmsg(FILE *file, const char *fmt, va_list ap)
{
const char *str;
int num;
+#ifdef HAVE_STRERROR_R
+#define ERRBUFSIZE (80)
+ int olderrno;
+ char errbuf[ERRBUFSIZE];
+#endif
+ char *errmsg;
if ((unset(SHINSTDIN) || locallevel) && lineno)
fprintf(file, "%ld: ", (long)lineno);
@@ -304,12 +310,39 @@ zerrmsg(FILE *file, const char *fmt, va_list ap)
errflag = 1;
return;
}
+#ifdef HAVE_STRERROR_R
+ /*
+ * There are two incompatible strerror_r()s floating round.
+ * The GNU extension refuses to copy the message into the
+ * buffer if it can return a constant string. To suppress it
+ * we need to define _XOPEN_SOURCE to 600. I don't dare do
+ * this because we're already depending on _GNU_SOURCE. So
+ * try to handle both by looking for errno being set (for the
+ * standard version failing) or errbuf being left untouched
+ * (for the GNU version). One presumes that if strerror_r()
+ * didn't copy anything to errbuf, then it's safe to
+ * call strerror() to get the string.
+ *
+ * This is a mess, but it's about a decade and half
+ * too late to shirk from messes in the source.
+ */
+ olderrno = errno;
+ errno = 0;
+ errbuf[0] = '\0';
+ strerror_r(num, errbuf, ERRBUFSIZE);
+ if (errno || errbuf[0] == '\0')
+ errmsg = strerror(num);
+ else
+ errmsg = errbuf;
+ errno = olderrno;
+#else
+ errmsg = strerror(num);
+#endif
/* If the message is not about I/O problems, it looks better *
* if we uncapitalize the first letter of the message */
if (num == EIO)
- fputs(strerror(num), file);
+ fputs(errmsg, file);
else {
- char *errmsg = strerror(num);
fputc(tulower(errmsg[0]), file);
fputs(errmsg + 1, file);
}