xref: /dflybsd-src/contrib/grep/lib/strerror.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
195b7b453SJohn Marino /* strerror.c --- POSIX compatible system error routine
295b7b453SJohn Marino 
3*09d4459fSDaniel Fojt    Copyright (C) 2007-2020 Free Software Foundation, Inc.
495b7b453SJohn Marino 
595b7b453SJohn Marino    This program is free software: you can redistribute it and/or modify
695b7b453SJohn Marino    it under the terms of the GNU General Public License as published by
795b7b453SJohn Marino    the Free Software Foundation; either version 3 of the License, or
895b7b453SJohn Marino    (at your option) any later version.
995b7b453SJohn Marino 
1095b7b453SJohn Marino    This program is distributed in the hope that it will be useful,
1195b7b453SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1295b7b453SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1395b7b453SJohn Marino    GNU General Public License for more details.
1495b7b453SJohn Marino 
1595b7b453SJohn Marino    You should have received a copy of the GNU General Public License
16*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
1795b7b453SJohn Marino 
1895b7b453SJohn Marino #include <config.h>
1995b7b453SJohn Marino 
20200fbe8dSJohn Marino /* Specification.  */
2195b7b453SJohn Marino #include <string.h>
2295b7b453SJohn Marino 
2395b7b453SJohn Marino #include <errno.h>
2495b7b453SJohn Marino #include <stdio.h>
25200fbe8dSJohn Marino #include <stdlib.h>
26200fbe8dSJohn Marino #include <string.h>
2795b7b453SJohn Marino 
2895b7b453SJohn Marino #include "intprops.h"
29200fbe8dSJohn Marino #include "strerror-override.h"
30200fbe8dSJohn Marino #include "verify.h"
3195b7b453SJohn Marino 
3295b7b453SJohn Marino /* Use the system functions, not the gnulib overrides in this file.  */
3395b7b453SJohn Marino #undef sprintf
3495b7b453SJohn Marino 
3595b7b453SJohn Marino char *
strerror(int n)36200fbe8dSJohn Marino strerror (int n)
37200fbe8dSJohn Marino #undef strerror
3895b7b453SJohn Marino {
39200fbe8dSJohn Marino   static char buf[STACKBUF_LEN];
40200fbe8dSJohn Marino   size_t len;
4195b7b453SJohn Marino 
42200fbe8dSJohn Marino   /* Cast away const, due to the historical signature of strerror;
43200fbe8dSJohn Marino      callers should not be modifying the string.  */
44200fbe8dSJohn Marino   const char *msg = strerror_override (n);
4595b7b453SJohn Marino   if (msg)
4695b7b453SJohn Marino     return (char *) msg;
4795b7b453SJohn Marino 
48200fbe8dSJohn Marino   msg = strerror (n);
4995b7b453SJohn Marino 
50200fbe8dSJohn Marino   /* Our strerror_r implementation might use the system's strerror
51200fbe8dSJohn Marino      buffer, so all other clients of strerror have to see the error
52200fbe8dSJohn Marino      copied into a buffer that we manage.  This is not thread-safe,
53200fbe8dSJohn Marino      even if the system strerror is, but portable programs shouldn't
54200fbe8dSJohn Marino      be using strerror if they care about thread-safety.  */
55200fbe8dSJohn Marino   if (!msg || !*msg)
5695b7b453SJohn Marino     {
57200fbe8dSJohn Marino       static char const fmt[] = "Unknown error %d";
58200fbe8dSJohn Marino       verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n));
59200fbe8dSJohn Marino       sprintf (buf, fmt, n);
60200fbe8dSJohn Marino       errno = EINVAL;
61200fbe8dSJohn Marino       return buf;
6295b7b453SJohn Marino     }
6395b7b453SJohn Marino 
64200fbe8dSJohn Marino   /* Fix STACKBUF_LEN if this ever aborts.  */
65200fbe8dSJohn Marino   len = strlen (msg);
66200fbe8dSJohn Marino   if (sizeof buf <= len)
67200fbe8dSJohn Marino     abort ();
6895b7b453SJohn Marino 
69*09d4459fSDaniel Fojt   memcpy (buf, msg, len + 1);
70*09d4459fSDaniel Fojt   return buf;
71200fbe8dSJohn Marino }
72