summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorwes <wes@FreeBSD.org>2001-12-07 06:28:58 +0000
committerwes <wes@FreeBSD.org>2001-12-07 06:28:58 +0000
commitfc6e3f432826fe9d9a9d2d05e295a7c7d11d259e (patch)
tree13ab748ad6a3bd42035b82a51f7ead77dbbf376b /lib
parent9aa8f2242aaf9263e01dbd9fb9be9cd2d1a14c2b (diff)
downloadFreeBSD-src-fc6e3f432826fe9d9a9d2d05e295a7c7d11d259e.zip
FreeBSD-src-fc6e3f432826fe9d9a9d2d05e295a7c7d11d259e.tar.gz
Make strerror and strerror_r use sys_errlist[0] for errnum = 0. Be
more careful about reporting truncation with ERANGE in strerror_r. Set errno to EINVAL for "unknown" errnum in strerror as required by P1003.1-200x Draft June 14, 2001. More carefully document the handling of strerrbuf when errors (ERANGE, EINVAL) are encountered in strerror_r. Reviewed by: bde (ongoing discussion)
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/string/strerror.315
-rw-r--r--lib/libc/string/strerror.c23
2 files changed, 32 insertions, 6 deletions
diff --git a/lib/libc/string/strerror.3 b/lib/libc/string/strerror.3
index 037b138..2ed92d6 100644
--- a/lib/libc/string/strerror.3
+++ b/lib/libc/string/strerror.3
@@ -110,8 +110,15 @@ returns an error message string containing
.Dq Li "Unknown error:\ "
followed by the error number in decimal, while
.Fn strerror_r
-returns
+leaves
+.Fa strerrbuf
+unchanged and returns
.Er EINVAL .
+Error numbers recognized by this implementation fall in
+the range 0 <=
+.Fa errnum
+<
+.Fa sys_nerr .
.Pp
If insufficient storage is provided in
.Fa strerrbuf
@@ -121,9 +128,11 @@ to contain the error string,
.Fn strerror_r
returns
.Er ERANGE
-and the contents of
+and
.Fa strerrbuf
-are indeterminate.
+will contain an error message that has been truncated and nul
+terminated to fit the length specified by
+.Fa buflen .
.Pp
The message strings can be accessed directly using the external
array
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
index e0f4cd3..55840f1 100644
--- a/lib/libc/string/strerror.c
+++ b/lib/libc/string/strerror.c
@@ -46,9 +46,9 @@ strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
int len;
- if ((errnum > 0) && (errnum < sys_nerr)) {
+ if ((errnum >= 0) && (errnum < sys_nerr)) {
len = strlcpy(strerrbuf, (char *)sys_errlist[errnum], buflen);
- return ((len <= buflen) ? 0 : ERANGE);
+ return ((len < buflen) ? 0 : ERANGE);
}
return (EINVAL);
}
@@ -71,10 +71,15 @@ strerror(num)
char tmp[NUMLEN]; /* temporary number */
static char ebuf[EBUFLEN]; /* error message */
- if ((num > 0) && (num < sys_nerr))
+ if ((num >= 0) && (num < sys_nerr))
return ((char *)sys_errlist[num]);
/*
+ * Set errno to EINVAL per P1003.1-200x Draft June 14, 2001.
+ */
+ errno = EINVAL;
+
+ /*
* Print unknown errno by hand so we don't link to stdio(3).
* This collects the ASCII digits in reverse order.
*/
@@ -106,8 +111,20 @@ main()
char mybuf[64];
int ret;
+ errno = 0;
+
+ printf("strerror(0) yeilds: %s\n", strerror(0));
+ printf("strerror(1) yeilds: %s\n", strerror(1));
printf("strerror(47) yeilds: %s\n", strerror(47));
+ printf("strerror(sys_nerr - 1) yeilds: %s\n", strerror(sys_nerr - 1));
+ printf("errno = %d\n", errno); errno = 0;
+
+ printf("strerror(sys_nerr) yeilds: %s\n", strerror(sys_nerr));
+ printf("errno = %d\n", errno); errno = 0;
+
printf("strerror(437) yeilds: %s\n", strerror(437));
+ printf("errno = %d\n", errno); errno = 0;
+
printf("strerror(LONG_MAX) yeilds: %s\n", strerror(LONG_MAX));
printf("strerror(LONG_MIN) yeilds: %s\n", strerror(LONG_MIN));
printf("strerror(ULONG_MAX) yeilds: %s\n", strerror(ULONG_MAX));
OpenPOWER on IntegriCloud