1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* util/support/strerror_r.c - strerror_r compatibility shim */ 3 /* 4 * Copyright (C) 2014 by the Massachusetts Institute of Technology. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <k5-platform.h> 34 #undef strerror_r 35 36 #if defined(_WIN32) 37 38 /* Implement strerror_r in terms of strerror_s. */ 39 int 40 k5_strerror_r(int errnum, char *buf, size_t buflen) 41 { 42 int st; 43 44 st = strerror_s(buf, buflen, errnum); 45 if (st != 0) { 46 errno = st; 47 return -1; 48 } 49 return 0; 50 } 51 52 #elif !defined(HAVE_STRERROR_R) 53 54 /* Implement strerror_r in terms of strerror (not thread-safe). */ 55 int 56 k5_strerror_r(int errnum, char *buf, size_t buflen) 57 { 58 if (strlcpy(buf, strerror(errnum), buflen) >= buflen) { 59 errno = ERANGE; 60 return -1; 61 } 62 return 0; 63 } 64 65 #elif defined(STRERROR_R_CHAR_P) 66 67 /* 68 * Implement the POSIX strerror_r API in terms of the GNU strerror_r, which 69 * returns a pointer to either the caller buffer or a constant string. This is 70 * the default version on glibc systems when _GNU_SOURCE is defined. 71 */ 72 int 73 k5_strerror_r(int errnum, char *buf, size_t buflen) 74 { 75 const char *str; 76 77 str = strerror_r(errnum, buf, buflen); 78 if (str != buf) { 79 if (strlcpy(buf, str, buflen) >= buflen) { 80 errno = ERANGE; 81 return -1; 82 } 83 } 84 return 0; 85 } 86 87 #else 88 89 /* Define a stub in terms of the real strerror_r, just to simplify the library 90 * export list. This shouldn't get used. */ 91 int 92 k5_strerror_r(int errnum, char *buf, size_t buflen) 93 { 94 return strerror_r(errnum, buf, buflen); 95 } 96 97 #endif 98