PR/30845: Luke Mewburn: strerror_r(3) missing

- Merge 4.4BSD strerror.3 man page changes that summarize information
  for all the error printing functions. This makes the perror(3) page
  obsolete.
- Implement all error functions in terms of strerror_r(), including
  __strerror() which is not used internally. Can it be removed?
- Bump version for strerror_r
This commit is contained in:
christos 2005-07-28 16:26:29 +00:00
parent 292dcda123
commit 1cf13731b1
9 changed files with 263 additions and 167 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.165 2005/07/06 14:43:24 drochner Exp $ # $NetBSD: shlib_version,v 1.166 2005/07/28 16:26:29 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing # Remember to update distrib/sets/lists/base/shl.* when changing
# #
# things we wish to do on next major version bump: # things we wish to do on next major version bump:
@ -17,4 +17,4 @@
# - libc/net/getnet{ent,namadr}.c, netdb.h: remove __n_pad0 # - libc/net/getnet{ent,namadr}.c, netdb.h: remove __n_pad0
# #
major=12 major=12
minor=130 minor=131

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91 # from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
# $NetBSD: Makefile.inc,v 1.31 2005/06/12 05:49:12 lukem Exp $ # $NetBSD: Makefile.inc,v 1.32 2005/07/28 16:26:29 christos Exp $
# stdio sources # stdio sources
.PATH: ${.CURDIR}/stdio .PATH: ${.CURDIR}/stdio
@ -32,7 +32,7 @@ SRCS+= _fileno.c _fseeko.c _ftello.c
MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \ MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \
flockfile.3 fopen.3 fparseln.3 fputs.3 fputws.3 fread.3 fseek.3 \ flockfile.3 fopen.3 fparseln.3 fputs.3 fputws.3 fread.3 fseek.3 \
funopen.3 fwide.3 getc.3 getwc.3 mktemp.3 perror.3 printf.3 \ funopen.3 fwide.3 getc.3 getwc.3 mktemp.3 printf.3 \
putc.3 putwc.3 remove.3 scanf.3 setbuf.3 stdio.3 tmpnam.3 \ putc.3 putwc.3 remove.3 scanf.3 setbuf.3 stdio.3 tmpnam.3 \
ungetc.3 ungetwc.3 wprintf.3 wscanf.3 ungetc.3 ungetwc.3 wprintf.3 wscanf.3

View File

@ -1,81 +0,0 @@
.\" $NetBSD: perror.3,v 1.10 2003/08/07 16:43:28 agc Exp $
.\"
.\" Copyright (c) 1980, 1991 Regents of the University of California.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the American National Standards Committee X3, on Information
.\" Processing Systems.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)strerror.3 6.9 (Berkeley) 6/29/91
.\"
.Dd June 29, 1991
.Dt PERROR 3
.Os
.Sh NAME
.Nm perror
.Nd write error messages to standard error
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In stdio.h
.Ft void
.Fn perror "const char *string"
.Sh DESCRIPTION
The
.Fn perror
function looks up the language-dependent error message string affiliated
with an error number and writes it, followed by a new-line, to the
standard error stream.
.Pp
If the argument
.Fa string
is
.Pf non- Dv NULL
it is prepended to the message string and separated from it by
a colon and a space
.Pq Ql \&:\ \& .
If
.Fa string
is
.Dv NULL
only the error message string is printed.
.Pp
The contents of the error message string is the same as those returned by
.Fn strerror
with argument
.Fa errno .
.Sh SEE ALSO
.Xr intro 2 ,
.Xr psignal 3 ,
.Xr setlocale 3 ,
.Xr strerror 3
.Sh STANDARDS
The
.Fn perror
function conforms to
.St -ansiC .

View File

@ -1,4 +1,4 @@
/* $NetBSD: perror.c,v 1.22 2003/08/07 16:43:28 agc Exp $ */ /* $NetBSD: perror.c,v 1.23 2005/07/28 16:26:29 christos Exp $ */
/* /*
* Copyright (c) 1988, 1993 * Copyright (c) 1988, 1993
@ -34,24 +34,23 @@
#if 0 #if 0
static char sccsid[] = "@(#)perror.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)perror.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: perror.c,v 1.22 2003/08/07 16:43:28 agc Exp $"); __RCSID("$NetBSD: perror.c,v 1.23 2005/07/28 16:26:29 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "extern.h" #include "extern.h"
/* /*
* Since perror() is not allowed to change the contents of strerror()'s * Since perror() is not allowed to change the contents of strerror()'s
* static buffer, both functions supply their own buffers to the * static buffer, both functions supply their own buffers to strerror_r().
* internal function __strerror().
*/ */
void void
perror(s) perror(const char *s)
const char *s;
{ {
const char *separator; const char *separator;
char buf[NL_TEXTMAX]; char buf[NL_TEXTMAX];
@ -63,6 +62,6 @@ perror(s)
else else
separator = ": "; separator = ": ";
(void)fprintf(stderr, "%s%s%s\n", s, separator, (void)strerror_r(errno, buf, sizeof(buf));
__strerror(errno, buf, sizeof(buf))); (void)fprintf(stderr, "%s%s%s\n", s, separator, buf);
} }

View File

@ -1,12 +1,12 @@
# from: @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # from: @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
# $NetBSD: Makefile.inc,v 1.56 2005/03/14 03:13:53 perry Exp $ # $NetBSD: Makefile.inc,v 1.57 2005/07/28 16:26:29 christos Exp $
# string sources # string sources
.PATH: ${ARCHDIR}/string ${.CURDIR}/string .PATH: ${ARCHDIR}/string ${.CURDIR}/string
SRCS+= bm.c strcasecmp.c strcasestr.c strcoll.c strdup.c strerror.c \ SRCS+= bm.c strcasecmp.c strcasestr.c strcoll.c strdup.c strerror.c \
strlcat.c strlcpy.c strmode.c strsignal.c strtok.c strtok_r.c \ strlcat.c strlcpy.c strmode.c strsignal.c strtok.c strtok_r.c \
strxfrm.c __strerror.c __strsignal.c strxfrm.c __strerror.c __strsignal.c strerror_r.c
# wide char # wide char
SRCS+= wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ SRCS+= wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
@ -67,6 +67,8 @@ MLINKS+=strcpy.3 strncpy.3
MLINKS+=strlcpy.3 strlcat.3 MLINKS+=strlcpy.3 strlcat.3
MLINKS+=strstr.3 strcasestr.3 MLINKS+=strstr.3 strcasestr.3
MLINKS+=strtok.3 strtok_r.3 MLINKS+=strtok.3 strtok_r.3
MLINKS+=strerror.3 strerror_r.3 strerror.3 perror.3 \
strerror.3 sys_errlist.3 strerror.3 sys_nerr.3
MLINKS+=wmemchr.3 wmemcmp.3 wmemchr.3 wmemcpy.3 \ MLINKS+=wmemchr.3 wmemcmp.3 wmemchr.3 wmemcpy.3 \
wmemchr.3 wmemmove.3 wmemchr.3 wmemset.3 \ wmemchr.3 wmemmove.3 wmemchr.3 wmemset.3 \
wmemchr.3 wcscat.3 wmemchr.3 wcschr.3 \ wmemchr.3 wcscat.3 wmemchr.3 wcschr.3 \

View File

@ -1,4 +1,4 @@
/* $NetBSD: __strerror.c,v 1.21 2003/08/07 16:43:46 agc Exp $ */ /* $NetBSD: __strerror.c,v 1.22 2005/07/28 16:26:29 christos Exp $ */
/* /*
* Copyright (c) 1988 Regents of the University of California. * Copyright (c) 1988 Regents of the University of California.
@ -34,7 +34,7 @@
#if 0 #if 0
static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91"; static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
#else #else
__RCSID("$NetBSD: __strerror.c,v 1.21 2003/08/07 16:43:46 agc Exp $"); __RCSID("$NetBSD: __strerror.c,v 1.22 2005/07/28 16:26:29 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
@ -51,48 +51,12 @@ __RCSID("$NetBSD: __strerror.c,v 1.21 2003/08/07 16:43:46 agc Exp $");
#include "extern.h" #include "extern.h"
/* /*
* Since perror() is not allowed to change the contents of strerror()'s * Compatibility. Can it be removed?
* static buffer, both functions supply their own buffers to the
* internal function __strerror().
*/ */
const char * const char *
__strerror(num, buf, buflen) __strerror(int num, char *buf, size_t buflen)
int num;
char *buf;
size_t buflen;
{ {
#define UPREFIX "Unknown error: %u" (void)strerror_r(num, buf, buflen);
unsigned int errnum;
#ifdef NLS
int saved_errno = errno;
nl_catd catd ;
catd = catopen("libc", NL_CAT_LOCALE);
#endif
_DIAGASSERT(buf != NULL);
errnum = num; /* convert to unsigned */
if (errnum < (unsigned int) sys_nerr) {
#ifdef NLS
(void)strlcpy(buf, catgets(catd, 1, (int)errnum,
sys_errlist[errnum]), buflen);
#else
return(sys_errlist[errnum]);
#endif
} else {
#ifdef NLS
snprintf(buf, buflen,
catgets(catd, 1, 0xffff, UPREFIX), errnum);
#else
snprintf(buf, buflen, UPREFIX, errnum);
#endif
}
#ifdef NLS
catclose(catd);
errno = saved_errno;
#endif
return buf; return buf;
} }

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 1980, 1991 Regents of the University of California. .\" Copyright (c) 1980, 1991, 1993
.\" All rights reserved. .\" The Regents of the University of California. All rights reserved.
.\" .\"
.\" This code is derived from software contributed to Berkeley by .\" This code is derived from software contributed to Berkeley by
.\" the American National Standards Committee X3, on Information .\" the American National Standards Committee X3, on Information
@ -13,7 +13,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright .\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the .\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution. .\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors .\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software .\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission. .\" without specific prior written permission.
.\" .\"
@ -29,36 +29,155 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 .\" @(#)strerror.3 8.1 (Berkeley) 6/9/93
.\" $NetBSD: strerror.3,v 1.10 2003/08/07 16:43:50 agc Exp $ .Dd July 28, 2005
.\"
.Dd June 29, 1991
.Dt STRERROR 3 .Dt STRERROR 3
.Os .Os
.Sh NAME .Sh NAME
.Nm strerror .Nm perror ,
.Nd get error message string .Nm strerror ,
.Nm strerror_r ,
.Nm sys_errlist ,
.Nm sys_nerr
.Nd system error messages
.Sh LIBRARY .Sh LIBRARY
.Lb libc .Lb libc
.Sh SYNOPSIS .Sh SYNOPSIS
.In stdio.h
.Ft void
.Fn perror "const char *string"
.In errno.h
.Vt extern const char * const sys_errlist[] ;
.Vt extern const int sys_nerr ;
.In string.h .In string.h
.Ft char * .Ft "char *"
.Fn strerror "int errnum" .Fn strerror "int errnum"
.Ft int
.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Fn strerror .Fn strerror ,
function returns a pointer to the language-dependent error message .Fn strerror_r
string affiliated with an error number. and
.Fn perror
functions look up the language-dependent error message
string corresponding with an error number.
.Pp .Pp
The array pointed to is not to be modified by the program, but may be
overwritten by subsequent calls to
.Fn strerror .
.Sh SEE ALSO
.Xr intro 2 ,
.Xr perror 3 ,
.Xr setlocale 3
.Sh STANDARDS
The The
.Fn strerror .Fn strerror
function accepts an error number argument
.Fa errnum
and returns a pointer to the corresponding
message string.
.Pp
The
.Fn strerror_r
function renders the same result into
.Fa strerrbuf
for a maximum of
.Fa buflen
characters and returns 0 upon success.
.Pp
The
.Fn perror
function finds the error message corresponding to the current
value of the global variable
.Va errno
.Pq Xr intro 2
and writes it, followed by a newline, to the
standard error file descriptor.
If the argument
.Fa string
is
.Pf non- Dv NULL
and does not point to the null character,
this string is prepended to the message
string and separated from it by
a colon and space
.Pq Dq Li ":\ " ;
otherwise, only the error message string is printed.
.Pp
If the error number is not recognized, these functions return an error message
string containing
.Dq Li "Unknown error:\ "
followed by the error number in decimal.
The
.Fn strerror
and
.Fn strerror_r
functions return
.Er EINVAL
as a warning.
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
(as specified in
.Fa buflen )
to contain the error string,
.Fn strerror_r
returns
.Er ERANGE
and
.Fa strerrbuf
will contain an error message that has been truncated and
.Dv NUL
terminated to fit the length specified by
.Fa buflen .
.Pp
The message strings can be accessed directly using the external
array
.Va sys_errlist .
The external value
.Va sys_nerr
contains a count of the messages in
.Va sys_errlist .
The use of these variables is deprecated;
.Fn strerror
or
.Fn strerror_r
should be used instead.
.Sh SEE ALSO
.Xr intro 2 ,
.Xr psignal 3
.Sh STANDARDS
The
.Fn perror
and
.Fn strerror
functions conform to
.St -isoC-99 .
The
.Fn strerror_r
function conforms to function conforms to
.St -ansiC . .St -p1003.1-2001 .
.Sh HISTORY
The
.Fn strerror
and
.Fn perror
functions first appeared in
.Bx 4.4 .
The
.Fn strerror_r
function first appeared in
.Nx 4.0
.Sh BUGS
For unknown error numbers, the
.Fn strerror
function will return its result in a static buffer which
may be overwritten by subsequent calls.
.Pp
The return type for
.Fn strerror
is missing a type-qualifier; it should actually be
.Vt const char * .
.Pp
Programs that use the deprecated
.Va sys_errlist
variable often fail to compile because they declare it
inconsistently.

View File

@ -1,4 +1,4 @@
/* $NetBSD: strerror.c,v 1.12 2003/08/07 16:43:51 agc Exp $ */ /* $NetBSD: strerror.c,v 1.13 2005/07/28 16:26:29 christos Exp $ */
/* /*
* Copyright (c) 1988 Regents of the University of California. * Copyright (c) 1988 Regents of the University of California.
@ -34,26 +34,26 @@
#if 0 #if 0
static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91"; static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
#else #else
__RCSID("$NetBSD: strerror.c,v 1.12 2003/08/07 16:43:51 agc Exp $"); __RCSID("$NetBSD: strerror.c,v 1.13 2005/07/28 16:26:29 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <errno.h>
#include "extern.h" #include "extern.h"
/* /*
* Since perror() is not allowed to change the contents of strerror()'s * Since perror() is not allowed to change the contents of strerror()'s
* static buffer, both functions supply their own buffers to the * static buffer, both functions supply their own buffers to strerror_r()
* internal function __strerror().
*/ */
__aconst char * __aconst char *
strerror(num) strerror(int num)
int num;
{ {
static char buf[NL_TEXTMAX]; static char buf[NL_TEXTMAX];
int error = strerror_r(num, buf, sizeof(buf));
/* LINTED const castaway */ if (error)
return (__aconst char *)__strerror(num, buf, sizeof(buf)); errno = error;
return buf;
} }

View File

@ -0,0 +1,93 @@
/* $NetBSD: strerror_r.c,v 1.1 2005/07/28 16:26:29 christos Exp $ */
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
#else
__RCSID("$NetBSD: strerror_r.c,v 1.1 2005/07/28 16:26:29 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#ifdef NLS
#include <limits.h>
#include <nl_types.h>
#endif
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "extern.h"
int
strerror_r(int num, char *buf, size_t buflen)
{
#define UPREFIX "Unknown error: %u"
unsigned int errnum = num;
int retval = 0;
size_t slen;
#ifdef NLS
int saved_errno = errno;
nl_catd catd;
catd = catopen("libc", NL_CAT_LOCALE);
#endif
_DIAGASSERT(buf != NULL);
if (errnum < (unsigned int) sys_nerr) {
#ifdef NLS
slen = strlcpy(buf, catgets(catd, 1, (int)errnum,
sys_errlist[errnum]), buflen);
#else
slen = strlcpy(buf, sys_errlist[errnum], buflen);
#endif
} else {
#ifdef NLS
slen = snprintf(buf, buflen,
catgets(catd, 1, 0xffff, UPREFIX), errnum);
#else
slen = snprintf(buf, buflen, UPREFIX, errnum);
#endif
retval = EINVAL;
}
if (slen >= buflen)
retval = ERANGE;
#ifdef NLS
catclose(catd);
errno = saved_errno;
#endif
return retval;
}