Edit

IABSD.fr/src/lib/libc/string/strerror_r.c

Branch :

  • Show log

    Commit

  • Author : bluhm
    Date : 2016-10-19 16:26:16
    Hash : 3a9dd5c3
    Message : Remove the save_errno dance inside strerror_r(3). It is from the time when we had national language support. OK millert@

  • lib/libc/string/strerror_r.c
  • /* $OpenBSD: strerror_r.c,v 1.13 2016/10/19 16:26:16 bluhm Exp $ */
    /* Public Domain <marc@snafu.org> */
    
    #include <errno.h>
    #include <limits.h>
    #include <signal.h>
    #include <string.h>
    
    static size_t
    __digits10(unsigned int num)
    {
    	size_t i = 0;
    
    	do {
    		num /= 10;
    		i++;
    	} while (num != 0);
    
    	return i;
    }
    
    static int
    __itoa(int num, int sign, char *buffer, size_t start, size_t end)
    {
    	size_t pos;
    	unsigned int a;
    	int neg;
    
    	if (sign && num < 0) {
    		a = -num;
    		neg = 1;
    	}
    	else {
    		a = num;
    		neg = 0;
    	}
    
    	pos = start + __digits10(a);
    	if (neg)
    	    pos++;
    
    	if (pos < end)
    		buffer[pos] = '\0';
    	else
    		return ERANGE;
    	pos--;
    	do {
    		buffer[pos] = (a % 10) + '0';
    		pos--;
    		a /= 10;
    	} while (a != 0);
    	if (neg)
    		buffer[pos] = '-';
    	return 0;
    }
    
    
    static int
    __num2string(int num, int sign, int setid, char *buf, size_t buflen,
        const char * const list[], size_t max, const char *def)
    {
    	int ret = 0;
    	size_t len;
    
    	if (0 <= num && num < max) {
    		len = strlcpy(buf, list[num], buflen);
    		if (len >= buflen)
    			ret = ERANGE;
    	} else {
    		len = strlcpy(buf, def, buflen);
    		if (len >= buflen)
    			ret = ERANGE;
    		else {
    			ret = __itoa(num, sign, buf, len, buflen);
    			if (ret == 0)
    				ret = EINVAL;
    		}
    	}
    
    	return ret;
    }
    
    #define	UPREFIX	"Unknown error: "
    
    int
    strerror_r(int errnum, char *strerrbuf, size_t buflen)
    {
    	int ret_errno;
    
    	ret_errno = __num2string(errnum, 1, 1, strerrbuf, buflen,
    	    sys_errlist, sys_nerr, UPREFIX);
    
    	if (ret_errno)
    		errno = ret_errno;
    	return (ret_errno);
    }
    DEF_WEAK(strerror_r);
    
    #define USIGPREFIX "Unknown signal: "
    
    char *
    __strsignal(int num, char *buf)
    {
    	__num2string(num, 0, 2, buf, NL_TEXTMAX, sys_siglist, NSIG,
    	    USIGPREFIX);
    	return buf;
    }