105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* strerror.c --- POSIX compatible system error routine 2cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2007-2012 Free Software Foundation, Inc. 4cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project it under the terms of the GNU General Public License as published by 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3 of the License, or 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 9cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 10cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This program is distributed in the hope that it will be useful, 11cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project GNU General Public License for more details. 14cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 15cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project You should have received a copy of the GNU General Public License 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 19cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Specification. */ 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <string.h> 22cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <errno.h> 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdio.h> 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdlib.h> 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <string.h> 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "intprops.h" 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "strerror-override.h" 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "verify.h" 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the system functions, not the gnulib overrides in this file. */ 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#undef sprintf 34cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar * 36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstrerror (int n) 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#undef strerror 38cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang static char buf[STACKBUF_LEN]; 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang size_t len; 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Cast away const, due to the historical signature of strerror; 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang callers should not be modifying the string. */ 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang const char *msg = strerror_override (n); 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (msg) 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return (char *) msg; 47cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang msg = strerror (n); 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Our strerror_r implementation might use the system's strerror 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang buffer, so all other clients of strerror have to see the error 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang copied into a buffer that we manage. This is not thread-safe, 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang even if the system strerror is, but portable programs shouldn't 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang be using strerror if they care about thread-safety. */ 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!msg || !*msg) 56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang static char const fmt[] = "Unknown error %d"; 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang sprintf (buf, fmt, n); 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang errno = EINVAL; 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return buf; 62cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Fix STACKBUF_LEN if this ever aborts. */ 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang len = strlen (msg); 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (sizeof buf <= len) 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang return memcpy (buf, msg, len + 1); 70cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 71