RFA: Support Windows extended error numbers in safe_strerror

Daniel Jacobowitz
2006-02-03T21:55:01Z

This is an improved version of a patch Mark Mitchell submitted last
year. If you give strerror() anything above 42 (sys_nerr) on Windows,
it gives you back "Unknown error" - particularly unfortunate since
WSAECONNREFUSED is way above there, so connecting to a closed socket
will give you a generic error message. This patch lets us try an
OS-specific interface to fetch an error string.

[Actually you need my next patch too to get the connection refused message;
right now you'll get a timeout.]

Any comments on this patch?

--
Daniel Jacobowitz
CodeSourcery

2006-02-03 Daniel Jacobowitz <dan@codesourcery.com>

* utils.c (safe_strerror): Try to use FormatMessage for otherwise
unknown messages on Windows.

Index: src/gdb/utils.c
===================================================================
--- src.orig/gdb/utils.c 2006-02-03 15:13:03.000000000 -0500
+++ src/gdb/utils.c 2006-02-03 15:16:24.000000000 -0500
@@ -1,8 +1,8 @@
/* General utility routines for GDB, the GNU debugger.

Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
- Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.

This file is part of GDB.

@@ -36,6 +36,10 @@
#include <pc.h>
#endif

+#ifdef USE_WIN32API
+#include <windows.h>
+#endif
+
/* SunOS's curses.h has a '#define reg register' in it. Thank you Sun. */
#ifdef reg
#undef reg
@@ -847,7 +851,34 @@ safe_strerror (int errnum)
{
char *msg;

- msg = strerror (errnum);
+#ifdef USE_WIN32API
+ /* On Windows, strerror never returns NULL, but it returns a useless
+ string for anything above sys_nerr. Try a little harder to find
+ a system-provided error message in that case. */
+ if (errnum >= sys_nerr)
+ {
+ static char *buffer;
+
+ if (buffer)
+ LocalFree (buffer);
+
+ if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, errnum,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buffer, 0, NULL) != 0)
+ {
+ if (strcmp (buffer + strlen (buffer) - 3, ".\r\n") == 0)
+ buffer[strlen (buffer) - 3] = '\0';
+ return buffer;
+ }
+ else
+ msg = NULL;
+ }
+ else
+#endif
+ msg = strerror (errnum);
+
if (msg == NULL)
{
static char buf[32];