Import gdb-7.10.1
[dragonfly.git] / contrib / gdb-7 / gdb / common / mingw-strerror.c
1 /* Safe version of strerror for MinGW, for GDB, the GNU debugger.
2
3    Copyright (C) 2006-2015 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "common-defs.h"
21
22 #include <windows.h>
23
24 /* Implementation of safe_strerror as defined in common-utils.h.
25
26    The Windows runtime implementation of strerror never returns NULL,
27    but does return a useless string for anything above sys_nerr;
28    unfortunately this includes all socket-related error codes.
29    This replacement tries to find a system-provided error message.  */
30
31 char *
32 safe_strerror (int errnum)
33 {
34   static char *buffer;
35   int len;
36
37   if (errnum >= 0 && errnum < sys_nerr)
38     return strerror (errnum);
39
40   if (buffer)
41     {
42       LocalFree (buffer);
43       buffer = NULL;
44     }
45
46   if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
47                      | FORMAT_MESSAGE_FROM_SYSTEM,
48                      NULL, errnum,
49                      MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
50                      (LPTSTR) &buffer, 0, NULL) == 0)
51     {
52       static char buf[32];
53       xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
54       return buf;
55     }
56
57   /* Windows error messages end with a period and a CR-LF; strip that
58      out.  */
59   len = strlen (buffer);
60   if (len > 3 && strcmp (buffer + len - 3, ".\r\n") == 0)
61     buffer[len - 3] = '\0';
62
63   return buffer;
64 }