1、strerror的实现:
char *strerror(errnum)
int errnum;
{
extern int sys_nerr;
extern char *sys_errlist[];
static char ebuf[20];
if ((unsigned int)errnum < sys_nerr)
return(sys_errlist[errnum]);
(void)sprintf(ebuf, "Unknown error: %d", errnum);
return(ebuf);
}
在查看man手册 :man sys_nerr 有如下内容:
SYNOPSIS
#include <stdio.h>
void perror(const char *s);
#include <errno.h>
const char *sys_errlist[];
int sys_nerr;
int errno;
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
sys_errlist, sys_nerr: _BSD_SOURCE
DESCRIPTION
The routine perror() produces a message on the standard error output, describing the
last error encountered during a call to a system or library function. First (if s is
not NULL and *s is not a null byte ('\0')) the argument string s is printed, followed
by a colon and a blank. Then the message and a new-line.
To be of most use, the argument string should include the name of the function that
incurred the error. The error number is taken from the external variable errno, which
is set when errors occur but not cleared when non-erroneous calls are made.
The global error list sys_errlist[] indexed by errno can be used to obtain the error
message without the newline. The largest message number provided in the table is
sys_nerr -1. Be careful when directly accessing this list because new error values may
not have been added to sys_errlist[].
When a system call fails, it usually returns -1 and sets the variable errno to a value
describing what went wrong. (These values can be found in <errno.h>.) Many library
functions do likewise. The function perror() serves to translate this error code into
human-readable form. Note that errno is undefined after a successful library call:
this call may well change this variable, even though it succeeds, for example because
it internally used some other library function that failed. Thus, if a failing call is
not immediately followed by a call to perror(), the value of errno should be saved.
当运行上面的代码时,会有如下提示:
funte.c:(.text+0x8): warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
funte.c:(.text+0xe): warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
查看man 手册:man strerror
SYNOPSIS
#include <string.h>
char *strerror(int errnum);
int strerror_r(int errnum, char *buf, size_t buflen);
/* XSI-compliant */
char *strerror_r(int errnum, char *buf, size_t buflen);
/* GNU-specific */
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
The XSI-compliant version of strerror_r() is provided if:
(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
Otherwise, the GNU-specific version is provided.
DESCRIPTION
The strerror() function returns a pointer to a string that describes the error code
passed in the argument errnum, possibly using the LC_MESSAGES part of the current
locale to select the appropriate language. This string must not be modified by the
application, but may be modified by a subsequent call to perror(3) or strerror(). No
library function will modify this string.
The strerror_r() function is similar to strerror(), but is thread safe. This function
is available in two versions: an XSI-compliant version specified in POSIX.1-2001
(available since glibc 2.3.4), and a GNU-specific version (available since glibc 2.0).
The XSI-compliant version is provided with the feature test macros settings shown in
the SYNOPSIS; otherwise the GNU-specific version is provided. If no feature test
macros are explicitly defined, then (since glibc 2.4) _POSIX_SOURCE is defined by
default with the value 200112L, so that the XSI-compliant version of strerror_r() is
provided by default.
The XSI-compliant strerror_r() is preferred for portable applications. It returns the
error string in the user-supplied buffer buf of length buflen.
The GNU-specific strerror_r() returns a pointer to a string containing the error mes‐
sage. This may be either a pointer to a string that the function stores in buf, or a
pointer to some (immutable) static string (in which case buf is unused). If the func‐
tion stores a string in buf, then at most buflen bytes are stored (the string may be
truncated if buflen is too small) and the string always includes a terminating null
byte.