* PATCH: Windows sockets
@ 2005-03-26 1:27 Mark Mitchell
2005-03-26 2:09 ` Christopher Faylor
2005-03-26 8:47 ` Mark Kettenis
0 siblings, 2 replies; 9+ messages in thread
From: Mark Mitchell @ 2005-03-26 1:27 UTC (permalink / raw)
To: gdb-patches
Here's the first "interesting" patch for Windows support. This patch
modifies ser-tcp.c to support Windows, so that we can use a GDB
running on Windows to talk to a gdbserver process.
Here is a sumary of the changes in this patch:
1. Link with -lws2_32 on MinGW so we can use sockets.
2. In defs.h, define WINAPI so that source files know whether they are
supposed to use the Windows API.
3. Move ser_unix_readchar and friends (which were only barely
UNIX-specific) into ser-base.c, renaming appropriately.
4. Add a new member (read_prim) to struct serial_ops, and use it from
ser_base_readchar. The reason for this is that sockets must be
read with "recv" on Windows; plain "read" does not work. So, we
need a way to indicate which low-level primitive to use to read
from a file descriptor.
5. Make a handful of minor changes to ter-tcp.c to account for
differences in the BSD and Windows sockets APIs.
6. Tweak safe_strerror to deal with Windows sockets error codes.
Tested on x86_64-unknown-linux-gnu, to make sure I didn't break UNIX,
and cursorily on Windows (with other patches, not yet submitted).
OK to apply?
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-03-25 Mark Mitchell <mark@codesourcery.com>
* configure.ac: Link with -lws2_32 on mingw.
* configure: Regenerated.
* defs.h (WINAPI): Define, conditionally.
* ser-base.c (winsock2.h): Include it.
(fd_event): Use read_prim.
(ser_base_wait_for): Moved here from ser-unix.c.
(do_ser_base_readchar): Likewise.
(generic_readchar): Likewise.
(ser_base_readchar): Likewise.
* ser-base.h (generic_readchar): Declare.
(ser_base_readchar): Likewise.
* ser-pipe.c (_initialize_ser_pipe): Adjust for name changes.
* ser-tcp.c (winsock2.h): Include it.
(ETIMEDOUT): Define on Windows.
(closesocket): Define on UNIX.
(ioctlsocket): Likewise.
(net_open): Adjust for differences in socket functions between
Windows and UNIX.
(_initialize_ser_tcp): Adjust for name changes.
(net_read_prim): New function.
(net_write): Likewise.
* ser-unix.c (generic_readchar): Remove.
(ser_unix_wait_for): Likewise.
(do_unix_readchar): Likewise.
(ser_unix_readchar): Likewise.
(_initialize_ser_hardwire): Adjust for name changes.
(ser_unix_read_prim): New function.
* ser-unix.h (ser_unix_readchar): Remove.
(ser_unix_read_prim): Declare.
* serial.h (struct serial_ops): Add read_prim.
* utils.c (winerror.h): Include it.
(safe_strerror): Handle winsock errors.
Index: configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/configure.ac,v
retrieving revision 1.17
diff -c -5 -p -r1.17 configure.ac
*** configure.ac 25 Mar 2005 19:47:23 -0000 1.17
--- configure.ac 26 Mar 2005 01:00:29 -0000
*************** if test x$gdb_cv_os_cygwin = xyes; then
*** 1185,1194 ****
--- 1185,1201 ----
case "${target}" in
*cygwin*) WIN32LIBS="$WIN32LIBS -limagehlp"
;;
esac
fi
+
+ # The ser-tcp.c module requires sockets.
+ case ${host} in
+ *mingw32*)
+ WIN32LIBS="$WIN32LIBS -lwsock32"
+ ;;
+ esac
AC_SUBST(WIN32LIBS)
LIBGUI="../libgui/src/libgui.a"
GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
AC_SUBST(LIBGUI)
Index: defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.182
diff -c -5 -p -r1.182 defs.h
*** defs.h 17 Mar 2005 22:11:09 -0000 1.182
--- defs.h 26 Mar 2005 01:00:29 -0000
*************** extern int use_windows;
*** 1149,1158 ****
--- 1149,1162 ----
#ifndef SLASH_STRING
#define SLASH_STRING "/"
#endif
+ #if defined(__WIN32__) && !defined(__CYGWIN__)
+ #define WINAPI
+ #endif
+
/* Provide default definitions of PIDGET, TIDGET, and MERGEPID.
The name ``TIDGET'' is a historical accident. Many uses of TIDGET
in the code actually refer to a lightweight process id, i.e,
something that can be considered a process id in its own right for
certain purposes. */
Index: ser-base.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-base.c,v
retrieving revision 1.2
diff -c -5 -p -r1.2 ser-base.c
*** ser-base.c 25 Mar 2005 20:06:36 -0000 1.2
--- ser-base.c 26 Mar 2005 01:00:29 -0000
***************
*** 22,31 ****
--- 22,34 ----
#include "defs.h"
#include "serial.h"
#include "ser-unix.h"
#include "event-loop.h"
+ #ifdef WINAPI
+ #include <winsock2.h>
+ #endif
static timer_handler_func push_event;
static handler_func fd_event;
/* Event handling for ASYNC serial code.
*************** fd_event (int error, void *context)
*** 134,148 ****
{
/* Prime the input FIFO. The readchar() function is used to
pull characters out of the buffer. See also
generic_readchar(). */
int nr;
! do
! {
! nr = read (scb->fd, scb->buf, BUFSIZ);
! }
! while (nr == -1 && errno == EINTR);
if (nr == 0)
{
scb->bufcnt = SERIAL_EOF;
}
else if (nr > 0)
--- 137,147 ----
{
/* Prime the input FIFO. The readchar() function is used to
pull characters out of the buffer. See also
generic_readchar(). */
int nr;
! nr = scb->ops->read_prim (scb, BUFSIZ);
if (nr == 0)
{
scb->bufcnt = SERIAL_EOF;
}
else if (nr > 0)
*************** push_event (void *context)
*** 172,181 ****
--- 171,359 ----
scb->async_handler (scb, scb->async_context);
/* re-schedule */
reschedule (scb);
}
+ /* Wait for input on scb, with timeout seconds. Returns 0 on success,
+ otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
+
+ static int
+ ser_base_wait_for (struct serial *scb, int timeout)
+ {
+ while (1)
+ {
+ int numfds;
+ struct timeval tv;
+ fd_set readfds, exceptfds;
+
+ /* NOTE: Some OS's can scramble the READFDS when the select()
+ call fails (ex the kernel with Red Hat 5.2). Initialize all
+ arguments before each call. */
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (scb->fd, &readfds);
+ FD_SET (scb->fd, &exceptfds);
+
+ if (timeout >= 0)
+ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
+ else
+ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
+
+ if (numfds <= 0)
+ {
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+ }
+
+ return 0;
+ }
+ }
+
+ /* Read a character with user-specified timeout. TIMEOUT is number of seconds
+ to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
+ char if successful. Returns -2 if timeout expired, EOF if line dropped
+ dead, or -3 for any other error (see errno in that case). */
+
+ static int
+ do_ser_base_readchar (struct serial *scb, int timeout)
+ {
+ int status;
+ int delta;
+
+ /* We have to be able to keep the GUI alive here, so we break the
+ original timeout into steps of 1 second, running the "keep the
+ GUI alive" hook each time through the loop.
+
+ Also, timeout = 0 means to poll, so we just set the delta to 0,
+ so we will only go through the loop once. */
+
+ delta = (timeout == 0 ? 0 : 1);
+ while (1)
+ {
+
+ /* N.B. The UI may destroy our world (for instance by calling
+ remote_stop,) in which case we want to get out of here as
+ quickly as possible. It is not safe to touch scb, since
+ someone else might have freed it. The
+ deprecated_ui_loop_hook signals that we should exit by
+ returning 1. */
+
+ if (deprecated_ui_loop_hook)
+ {
+ if (deprecated_ui_loop_hook (0))
+ return SERIAL_TIMEOUT;
+ }
+
+ status = ser_base_wait_for (scb, delta);
+ if (timeout > 0)
+ timeout -= delta;
+
+ /* If we got a character or an error back from wait_for, then we can
+ break from the loop before the timeout is completed. */
+
+ if (status != SERIAL_TIMEOUT)
+ {
+ break;
+ }
+
+ /* If we have exhausted the original timeout, then generate
+ a SERIAL_TIMEOUT, and pass it out of the loop. */
+
+ else if (timeout == 0)
+ {
+ status = SERIAL_TIMEOUT;
+ break;
+ }
+ }
+
+ if (status < 0)
+ return status;
+
+ status = scb->ops->read_prim (scb, BUFSIZ);
+
+ if (status <= 0)
+ {
+ if (status == 0)
+ return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
+ distinguish between EOF & timeouts
+ someday] */
+ else
+ return SERIAL_ERROR; /* Got an error from read */
+ }
+
+ scb->bufcnt = status;
+ scb->bufcnt--;
+ scb->bufp = scb->buf;
+ return *scb->bufp++;
+ }
+
+ /* Perform operations common to both old and new readchar. */
+
+ /* Return the next character from the input FIFO. If the FIFO is
+ empty, call the SERIAL specific routine to try and read in more
+ characters.
+
+ Initially data from the input FIFO is returned (fd_event()
+ pre-reads the input into that FIFO. Once that has been emptied,
+ further data is obtained by polling the input FD using the device
+ specific readchar() function. Note: reschedule() is called after
+ every read. This is because there is no guarentee that the lower
+ level fd_event() poll_event() code (which also calls reschedule())
+ will be called. */
+
+ int
+ generic_readchar (struct serial *scb, int timeout,
+ int (do_readchar) (struct serial *scb, int timeout))
+ {
+ int ch;
+ if (scb->bufcnt > 0)
+ {
+ ch = *scb->bufp;
+ scb->bufcnt--;
+ scb->bufp++;
+ }
+ else if (scb->bufcnt < 0)
+ {
+ /* Some errors/eof are are sticky. */
+ ch = scb->bufcnt;
+ }
+ else
+ {
+ ch = do_readchar (scb, timeout);
+ if (ch < 0)
+ {
+ switch ((enum serial_rc) ch)
+ {
+ case SERIAL_EOF:
+ case SERIAL_ERROR:
+ /* Make the error/eof stick. */
+ scb->bufcnt = ch;
+ break;
+ case SERIAL_TIMEOUT:
+ scb->bufcnt = 0;
+ break;
+ }
+ }
+ }
+ reschedule (scb);
+ return ch;
+ }
+
+ int
+ ser_base_readchar (struct serial *scb, int timeout)
+ {
+ return generic_readchar (scb, timeout, do_ser_base_readchar);
+ }
+
int
ser_base_write (struct serial *scb, const char *str, int len)
{
int cc;
Index: ser-base.h
===================================================================
RCS file: /cvs/src/src/gdb/ser-base.h,v
retrieving revision 1.2
diff -c -5 -p -r1.2 ser-base.h
*** ser-base.h 25 Mar 2005 20:06:36 -0000 1.2
--- ser-base.h 26 Mar 2005 01:00:29 -0000
***************
*** 23,32 ****
--- 23,35 ----
#define SER_BASE_H
struct serial;
struct ui_file;
+ extern int generic_readchar (struct serial *scb, int timeout,
+ int (*do_readchar) (struct serial *scb,
+ int timeout));
extern void reschedule (struct serial *scb);
extern int ser_base_flush_output (struct serial *scb);
extern int ser_base_flush_input (struct serial *scb);
extern int ser_base_send_break (struct serial *scb);
extern void ser_base_raw (struct serial *scb);
*************** extern int ser_base_setstopbits (struct
*** 44,50 ****
--- 47,54 ----
extern int ser_base_drain_output (struct serial *scb);
extern int ser_base_write (struct serial *scb, const char *str, int len);
extern void ser_base_async (struct serial *scb, int async_p);
+ extern int ser_base_readchar (struct serial *scb, int timeout);
#endif
Index: ser-pipe.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-pipe.c,v
retrieving revision 1.15
diff -c -5 -p -r1.15 ser-pipe.c
*** ser-pipe.c 25 Mar 2005 20:06:36 -0000 1.15
--- ser-pipe.c 26 Mar 2005 01:00:29 -0000
*************** _initialize_ser_pipe (void)
*** 142,152 ****
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "pipe";
ops->next = 0;
ops->open = pipe_open;
ops->close = pipe_close;
! ops->readchar = ser_unix_readchar;
ops->write = ser_base_write;
ops->flush_output = ser_base_flush_output;
ops->flush_input = ser_base_flush_input;
ops->send_break = ser_base_send_break;
ops->go_raw = ser_base_raw;
--- 142,152 ----
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "pipe";
ops->next = 0;
ops->open = pipe_open;
ops->close = pipe_close;
! ops->readchar = ser_base_readchar;
ops->write = ser_base_write;
ops->flush_output = ser_base_flush_output;
ops->flush_input = ser_base_flush_input;
ops->send_break = ser_base_send_break;
ops->go_raw = ser_base_raw;
*************** _initialize_ser_pipe (void)
*** 156,162 ****
--- 156,163 ----
ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
ops->setbaudrate = ser_base_setbaudrate;
ops->setstopbits = ser_base_setstopbits;
ops->drain_output = ser_base_drain_output;
ops->async = ser_base_async;
+ ops->read_prim = ser_unix_read_prim;
serial_add_interface (ops);
}
Index: ser-tcp.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-tcp.c,v
retrieving revision 1.20
diff -c -5 -p -r1.20 ser-tcp.c
*** ser-tcp.c 25 Mar 2005 20:06:36 -0000 1.20
--- ser-tcp.c 26 Mar 2005 01:00:29 -0000
***************
*** 32,46 ****
--- 32,54 ----
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> /* For FIONBIO. */
#endif
#include <sys/time.h>
+
+ #ifdef WINAPI
+ #include <winsock2.h>
+ #define ETIMEDOUT WSAETIMEDOUT
+ #else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
+ #define closesocket close
+ #define ioctlsocket ioctl
+ #endif
#include <signal.h>
#include "gdb_string.h"
static int net_open (struct serial *scb, const char *name);
*************** net_open (struct serial *scb, const char
*** 60,69 ****
--- 68,82 ----
char *port_str, hostname[100];
int n, port, tmp;
int use_udp;
struct hostent *hostent;
struct sockaddr_in sockaddr;
+ #ifdef WINAPI
+ u_long ioarg;
+ #else
+ int ioarg;
+ #endif
use_udp = 0;
if (strncmp (name, "udp:", 4) == 0)
{
use_udp = 1;
*************** net_open (struct serial *scb, const char
*** 106,123 ****
sockaddr.sin_port = htons (port);
memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
sizeof (struct in_addr));
/* set socket nonblocking */
! tmp = 1;
! ioctl (scb->fd, FIONBIO, &tmp);
/* Use Non-blocking connect. connect() will return 0 if connected already. */
n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
! if (n < 0 && errno != EINPROGRESS)
{
net_close (scb);
return -1;
}
if (n)
--- 119,147 ----
sockaddr.sin_port = htons (port);
memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
sizeof (struct in_addr));
/* set socket nonblocking */
! ioarg = 1;
! ioctlsocket (scb->fd, FIONBIO, &ioarg);
/* Use Non-blocking connect. connect() will return 0 if connected already. */
n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
! if (n < 0
! #ifdef WINAPI
! /* Under Windows, calling "connect" with a non-blocking socket
! results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */
! && WSAGetLastError() != WSAEWOULDBLOCK
! #else
! && errno != EINPROGRESS
! #endif
! )
{
+ #ifdef WINAPI
+ errno = WSAGetLastError();
+ #endif
net_close (scb);
return -1;
}
if (n)
*************** net_open (struct serial *scb, const char
*** 163,185 ****
/* Got something. Is it an error? */
{
int res, err, len;
len = sizeof(err);
! res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
if (res < 0 || err)
{
if (err)
errno = err;
net_close (scb);
return -1;
}
}
/* turn off nonblocking */
! tmp = 0;
! ioctl (scb->fd, FIONBIO, &tmp);
if (use_udp == 0)
{
/* Disable Nagle algorithm. Needed in some cases. */
tmp = 1;
--- 187,213 ----
/* Got something. Is it an error? */
{
int res, err, len;
len = sizeof(err);
! /* On Windows, the fourth parameter to getsockopt is a "char *";
! on UNIX systems it is generally "void *". The cast to "void *"
! is OK everywhere, since in C "void *" can be implicitly
! converted to any pointer type. */
! res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
if (res < 0 || err)
{
if (err)
errno = err;
net_close (scb);
return -1;
}
}
/* turn off nonblocking */
! ioarg = 0;
! ioctlsocket (scb->fd, FIONBIO, &ioarg);
if (use_udp == 0)
{
/* Disable Nagle algorithm. Needed in some cases. */
tmp = 1;
*************** static void
*** 200,224 ****
net_close (struct serial *scb)
{
if (scb->fd < 0)
return;
! close (scb->fd);
scb->fd = -1;
}
void
_initialize_ser_tcp (void)
{
! struct serial_ops *ops = XMALLOC (struct serial_ops);
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "tcp";
ops->next = 0;
ops->open = net_open;
ops->close = net_close;
! ops->readchar = ser_unix_readchar;
! ops->write = ser_base_write;
ops->flush_output = ser_base_flush_output;
ops->flush_input = ser_base_flush_input;
ops->send_break = ser_base_send_break;
ops->go_raw = ser_base_raw;
ops->get_tty_state = ser_base_get_tty_state;
--- 228,293 ----
net_close (struct serial *scb)
{
if (scb->fd < 0)
return;
! closesocket (scb->fd);
scb->fd = -1;
}
+ static int
+ net_read_prim (struct serial *scb, size_t count)
+ {
+ #ifdef WINAPI
+ /* Under Windows, we must use "recv" to read data from sockets. */
+ return recv (scb->fd, scb->buf, count, 0);
+ #else
+ return ser_unix_read_prim (scb, count);
+ #endif
+ }
+
+ static int
+ net_write (struct serial *scb, const char *str, int len)
+ {
+ #ifdef WINAPI
+ /* Under Windows, we must use "send" to send data to and from
+ sockets. */
+ int cc;
+
+ while (len > 0)
+ {
+ cc = send (scb->fd, str, len, 0);
+
+ if (cc < 0)
+ return 1;
+ len -= cc;
+ str += cc;
+ }
+ return 0;
+ #else
+ return ser_base_write (scb, str, len);
+ #endif
+ }
+
void
_initialize_ser_tcp (void)
{
! struct serial_ops *ops;
! #ifdef WINAPI
! WSADATA wsa_data;
! if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
! /* WinSock is unavailable. */
! return;
! #endif
! ops = XMALLOC (struct serial_ops);
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "tcp";
ops->next = 0;
ops->open = net_open;
ops->close = net_close;
! ops->readchar = ser_base_readchar;
! ops->write = net_write;
ops->flush_output = ser_base_flush_output;
ops->flush_input = ser_base_flush_input;
ops->send_break = ser_base_send_break;
ops->go_raw = ser_base_raw;
ops->get_tty_state = ser_base_get_tty_state;
*************** _initialize_ser_tcp (void)
*** 227,233 ****
--- 296,303 ----
ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
ops->setbaudrate = ser_base_setbaudrate;
ops->setstopbits = ser_base_setstopbits;
ops->drain_output = ser_base_drain_output;
ops->async = ser_base_async;
+ ops->read_prim = net_read_prim;
serial_add_interface (ops);
}
Index: ser-unix.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-unix.c,v
retrieving revision 1.24
diff -c -5 -p -r1.24 ser-unix.c
*** ser-unix.c 25 Mar 2005 20:06:36 -0000 1.24
--- ser-unix.c 26 Mar 2005 01:00:30 -0000
*************** struct hardwire_ttystate
*** 68,80 ****
static int hardwire_open (struct serial *scb, const char *name);
static void hardwire_raw (struct serial *scb);
static int wait_for (struct serial *scb, int timeout);
static int hardwire_readchar (struct serial *scb, int timeout);
static int do_hardwire_readchar (struct serial *scb, int timeout);
- static int generic_readchar (struct serial *scb, int timeout,
- int (*do_readchar) (struct serial *scb,
- int timeout));
static int rate_to_code (int rate);
static int hardwire_setbaudrate (struct serial *scb, int rate);
static void hardwire_close (struct serial *scb);
static int get_tty_state (struct serial *scb,
struct hardwire_ttystate * state);
--- 68,77 ----
*************** hardwire_raw (struct serial *scb)
*** 420,430 ****
For termio{s}, we actually just setup VTIME if necessary, and let the
timeout occur in the read() in hardwire_read().
*/
/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
! ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
flushed. . */
/* NOTE: cagney/1999-09-30: Much of the code below is dead. The only
possible values of the TIMEOUT parameter are ONE and ZERO.
Consequently all the code that tries to handle the possability of
--- 417,427 ----
For termio{s}, we actually just setup VTIME if necessary, and let the
timeout occur in the read() in hardwire_read().
*/
/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
! ser_base*() until the old TERMIOS/SGTTY/... timer code has been
flushed. . */
/* NOTE: cagney/1999-09-30: Much of the code below is dead. The only
possible values of the TIMEOUT parameter are ONE and ZERO.
Consequently all the code that tries to handle the possability of
*************** wait_for (struct serial *scb, int timeou
*** 540,556 ****
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
! ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
flushed. */
/* NOTE: cagney/1999-09-16: This function is not identical to
! ser_unix_readchar() as part of replacing it with ser_unix*()
merging will be required - this code handles the case where read()
! times out due to no data while ser_unix_readchar() doesn't expect
that. */
static int
do_hardwire_readchar (struct serial *scb, int timeout)
{
--- 537,553 ----
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
! ser_base*() until the old TERMIOS/SGTTY/... timer code has been
flushed. */
/* NOTE: cagney/1999-09-16: This function is not identical to
! ser_base_readchar() as part of replacing it with ser_base*()
merging will be required - this code handles the case where read()
! times out due to no data while ser_base_readchar() doesn't expect
that. */
static int
do_hardwire_readchar (struct serial *scb, int timeout)
{
*************** hardwire_close (struct serial *scb)
*** 861,1066 ****
return;
close (scb->fd);
scb->fd = -1;
}
-
\f
- /* Wait for input on scb, with timeout seconds. Returns 0 on success,
- otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
-
- static int
- ser_unix_wait_for (struct serial *scb, int timeout)
- {
- while (1)
- {
- int numfds;
- struct timeval tv;
- fd_set readfds, exceptfds;
-
- /* NOTE: Some OS's can scramble the READFDS when the select()
- call fails (ex the kernel with Red Hat 5.2). Initialize all
- arguments before each call. */
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- FD_ZERO (&readfds);
- FD_ZERO (&exceptfds);
- FD_SET (scb->fd, &readfds);
- FD_SET (scb->fd, &exceptfds);
-
- if (timeout >= 0)
- numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
- else
- numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
-
- if (numfds <= 0)
- {
- if (numfds == 0)
- return SERIAL_TIMEOUT;
- else if (errno == EINTR)
- continue;
- else
- return SERIAL_ERROR; /* Got an error from select or poll */
- }
-
- return 0;
- }
- }
-
- /* Read a character with user-specified timeout. TIMEOUT is number of seconds
- to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
- char if successful. Returns -2 if timeout expired, EOF if line dropped
- dead, or -3 for any other error (see errno in that case). */
-
- static int
- do_unix_readchar (struct serial *scb, int timeout)
- {
- int status;
- int delta;
-
- /* We have to be able to keep the GUI alive here, so we break the
- original timeout into steps of 1 second, running the "keep the
- GUI alive" hook each time through the loop.
-
- Also, timeout = 0 means to poll, so we just set the delta to 0,
- so we will only go through the loop once. */
-
- delta = (timeout == 0 ? 0 : 1);
- while (1)
- {
-
- /* N.B. The UI may destroy our world (for instance by calling
- remote_stop,) in which case we want to get out of here as
- quickly as possible. It is not safe to touch scb, since
- someone else might have freed it. The
- deprecated_ui_loop_hook signals that we should exit by
- returning 1. */
-
- if (deprecated_ui_loop_hook)
- {
- if (deprecated_ui_loop_hook (0))
- return SERIAL_TIMEOUT;
- }
-
- status = ser_unix_wait_for (scb, delta);
- if (timeout > 0)
- timeout -= delta;
-
- /* If we got a character or an error back from wait_for, then we can
- break from the loop before the timeout is completed. */
-
- if (status != SERIAL_TIMEOUT)
- {
- break;
- }
-
- /* If we have exhausted the original timeout, then generate
- a SERIAL_TIMEOUT, and pass it out of the loop. */
-
- else if (timeout == 0)
- {
- status = SERIAL_TIMEOUT;
- break;
- }
- }
-
- if (status < 0)
- return status;
-
- while (1)
- {
- status = read (scb->fd, scb->buf, BUFSIZ);
- if (status != -1 || errno != EINTR)
- break;
- }
-
- if (status <= 0)
- {
- if (status == 0)
- return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
- distinguish between EOF & timeouts
- someday] */
- else
- return SERIAL_ERROR; /* Got an error from read */
- }
-
- scb->bufcnt = status;
- scb->bufcnt--;
- scb->bufp = scb->buf;
- return *scb->bufp++;
- }
-
- /* Perform operations common to both old and new readchar. */
-
- /* Return the next character from the input FIFO. If the FIFO is
- empty, call the SERIAL specific routine to try and read in more
- characters.
-
- Initially data from the input FIFO is returned (fd_event()
- pre-reads the input into that FIFO. Once that has been emptied,
- further data is obtained by polling the input FD using the device
- specific readchar() function. Note: reschedule() is called after
- every read. This is because there is no guarentee that the lower
- level fd_event() poll_event() code (which also calls reschedule())
- will be called. */
-
- static int
- generic_readchar (struct serial *scb, int timeout,
- int (do_readchar) (struct serial *scb, int timeout))
- {
- int ch;
- if (scb->bufcnt > 0)
- {
- ch = *scb->bufp;
- scb->bufcnt--;
- scb->bufp++;
- }
- else if (scb->bufcnt < 0)
- {
- /* Some errors/eof are are sticky. */
- ch = scb->bufcnt;
- }
- else
- {
- ch = do_readchar (scb, timeout);
- if (ch < 0)
- {
- switch ((enum serial_rc) ch)
- {
- case SERIAL_EOF:
- case SERIAL_ERROR:
- /* Make the error/eof stick. */
- scb->bufcnt = ch;
- break;
- case SERIAL_TIMEOUT:
- scb->bufcnt = 0;
- break;
- }
- }
- }
- reschedule (scb);
- return ch;
- }
-
- int
- ser_unix_readchar (struct serial *scb, int timeout)
- {
- return generic_readchar (scb, timeout, do_unix_readchar);
- }
\f
void
_initialize_ser_hardwire (void)
{
struct serial_ops *ops = XMALLOC (struct serial_ops);
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "hardwire";
ops->next = 0;
ops->open = hardwire_open;
ops->close = hardwire_close;
! /* FIXME: Don't replace this with the equivalent ser_unix*() until
the old TERMIOS/SGTTY/... timer code has been flushed. cagney
1999-09-16. */
ops->readchar = hardwire_readchar;
ops->write = ser_base_write;
ops->flush_output = hardwire_flush_output;
--- 858,879 ----
return;
close (scb->fd);
scb->fd = -1;
}
\f
\f
void
_initialize_ser_hardwire (void)
{
struct serial_ops *ops = XMALLOC (struct serial_ops);
memset (ops, 0, sizeof (struct serial_ops));
ops->name = "hardwire";
ops->next = 0;
ops->open = hardwire_open;
ops->close = hardwire_close;
! /* FIXME: Don't replace this with the equivalent ser_base*() until
the old TERMIOS/SGTTY/... timer code has been flushed. cagney
1999-09-16. */
ops->readchar = hardwire_readchar;
ops->write = ser_base_write;
ops->flush_output = hardwire_flush_output;
*************** _initialize_ser_hardwire (void)
*** 1073,1079 ****
--- 886,907 ----
ops->noflush_set_tty_state = hardwire_noflush_set_tty_state;
ops->setbaudrate = hardwire_setbaudrate;
ops->setstopbits = hardwire_setstopbits;
ops->drain_output = hardwire_drain_output;
ops->async = ser_base_async;
+ ops->read_prim = ser_unix_read_prim;
serial_add_interface (ops);
}
+
+ int
+ ser_unix_read_prim (struct serial *scb, size_t count)
+ {
+ int status;
+
+ while (1)
+ {
+ status = read (scb->fd, scb->buf, count);
+ if (status != -1 || errno != EINTR)
+ break;
+ }
+ return status;
+ }
Index: ser-unix.h
===================================================================
RCS file: /cvs/src/src/gdb/ser-unix.h,v
retrieving revision 1.5
diff -c -5 -p -r1.5 ser-unix.h
*** ser-unix.h 25 Mar 2005 19:47:23 -0000 1.5
--- ser-unix.h 26 Mar 2005 01:00:30 -0000
***************
*** 20,27 ****
Boston, MA 02111-1307, USA. */
#ifndef SER_UNIX_H
#define SER_UNIX_H
! extern int ser_unix_readchar (struct serial *scb, int timeout);
#endif
--- 20,27 ----
Boston, MA 02111-1307, USA. */
#ifndef SER_UNIX_H
#define SER_UNIX_H
! extern int ser_unix_read_prim (struct serial *scb, size_t count);
#endif
Index: serial.h
===================================================================
RCS file: /cvs/src/src/gdb/serial.h,v
retrieving revision 1.10
diff -c -5 -p -r1.10 serial.h
*** serial.h 14 Jan 2005 01:59:20 -0000 1.10
--- serial.h 26 Mar 2005 01:00:30 -0000
*************** struct serial_ops
*** 230,239 ****
--- 230,242 ----
int (*drain_output) (struct serial *);
/* Change the serial device into/out of asynchronous mode, call
the specified function when ever there is something
interesting. */
void (*async) (struct serial *scb, int async_p);
+ /* Perform a low-level read operation, reading (at most) COUNT
+ bytes into SCB->BUF. */
+ int (*read_prim)(struct serial *scb, size_t count);
};
/* Add a new serial interface to the interface list */
extern void serial_add_interface (struct serial_ops * optable);
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.160
diff -c -5 -p -r1.160 utils.c
*** utils.c 18 Mar 2005 20:46:38 -0000 1.160
--- utils.c 26 Mar 2005 01:00:30 -0000
***************
*** 56,65 ****
--- 56,69 ----
#include "inferior.h" /* for signed_pointer_to_address */
#include <sys/param.h> /* For MAXPATHLEN */
+ #ifdef WINAPI
+ #include <winerror.h>
+ #endif
+
#include "gdb_curses.h"
#include "readline/readline.h"
#if !HAVE_DECL_MALLOC
*************** internal_warning (const char *file, int
*** 844,861 ****
char *
safe_strerror (int errnum)
{
char *msg;
! msg = strerror (errnum);
! if (msg == NULL)
{
! static char buf[32];
! xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
msg = buf;
}
return (msg);
}
/* Print the system error message for errno, and also mention STRING
as the file name for which the error was encountered.
--- 848,879 ----
char *
safe_strerror (int errnum)
{
char *msg;
+ static char buf[32];
! #ifdef WINAPI
! /* The strerror function only works for functions that set errno.
! In the case of Windows sockets, we can get error numbers that
! strerror cannot handle. */
! if (errnum > WSABASEERR)
{
! xsnprintf (buf, sizeof buf, "(winsock error %d)", errnum);
msg = buf;
}
+ else
+ #endif
+ {
+ msg = strerror (errnum);
+
+ if (msg == NULL)
+ {
+ xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
+ msg = buf;
+ }
+ }
return (msg);
}
/* Print the system error message for errno, and also mention STRING
as the file name for which the error was encountered.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 1:27 PATCH: Windows sockets Mark Mitchell
@ 2005-03-26 2:09 ` Christopher Faylor
2005-03-26 8:47 ` Mark Kettenis
1 sibling, 0 replies; 9+ messages in thread
From: Christopher Faylor @ 2005-03-26 2:09 UTC (permalink / raw)
To: Mark Mitchell, gdb-patches
On Fri, Mar 25, 2005 at 05:27:05PM -0800, Mark Mitchell wrote:
>Here's the first "interesting" patch for Windows support. This patch
>modifies ser-tcp.c to support Windows, so that we can use a GDB
>running on Windows to talk to a gdbserver process.
>
>Here is a sumary of the changes in this patch:
>
>1. Link with -lws2_32 on MinGW so we can use sockets.
>
>2. In defs.h, define WINAPI so that source files know whether they are
> supposed to use the Windows API.
>
>3. Move ser_unix_readchar and friends (which were only barely
> UNIX-specific) into ser-base.c, renaming appropriately.
>
>4. Add a new member (read_prim) to struct serial_ops, and use it from
> ser_base_readchar. The reason for this is that sockets must be
> read with "recv" on Windows; plain "read" does not work. So, we
> need a way to indicate which low-level primitive to use to read
> from a file descriptor.
>
>5. Make a handful of minor changes to ter-tcp.c to account for
> differences in the BSD and Windows sockets APIs.
>
>6. Tweak safe_strerror to deal with Windows sockets error codes.
>
>Tested on x86_64-unknown-linux-gnu, to make sure I didn't break UNIX,
>and cursorily on Windows (with other patches, not yet submitted).
>
>OK to apply?
The windows-specific configury parts look ok to me. That's all I
can approve, although the other bits look right too.
cgf
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 1:27 PATCH: Windows sockets Mark Mitchell
2005-03-26 2:09 ` Christopher Faylor
@ 2005-03-26 8:47 ` Mark Kettenis
2005-03-26 17:38 ` Mark Mitchell
1 sibling, 1 reply; 9+ messages in thread
From: Mark Kettenis @ 2005-03-26 8:47 UTC (permalink / raw)
To: mark; +Cc: gdb-patches
Date: Fri, 25 Mar 2005 17:27:05 -0800
From: Mark Mitchell <mark@codesourcery.com>
Here's the first "interesting" patch for Windows support. This patch
modifies ser-tcp.c to support Windows, so that we can use a GDB
running on Windows to talk to a gdbserver process.
Yikes. This is real ugly and I'm not too happy about this.
Here is a sumary of the changes in this patch:
1. Link with -lws2_32 on MinGW so we can use sockets.
Can't you just use a standard autoconf check to check for that library
instead of hardcoding it to be linked in on MinGW?
2. In defs.h, define WINAPI so that source files know whether they are
supposed to use the Windows API.
This is bad. Yet another #ifdef WINDHOOS when we really are trying to
get rid of those.
3. Move ser_unix_readchar and friends (which were only barely
UNIX-specific) into ser-base.c, renaming appropriately.
Fair enough.
4. Add a new member (read_prim) to struct serial_ops, and use it from
ser_base_readchar. The reason for this is that sockets must be
read with "recv" on Windows; plain "read" does not work. So, we
need a way to indicate which low-level primitive to use to read
from a file descriptor.
But write(2) does work and you don't need to use send(2). Oh you do
but things are not quite symmetric. Could you fix that? Isn't it a
better idea to change the #ifdef WINAPI in a #ifdef HAVE_RECV, add an
autoconf check for recv(2), and always prefer it over read(2) if
available for reading from a socket?
5. Make a handful of minor changes to ter-tcp.c to account for
differences in the BSD and Windows sockets APIs.
You mean that Windows doesn't have the proper BSD socket API even
though Microsoft stole^Wused the BSD TCP stack?
I really think these changes are too pervasive and that you really
need to create a ser-win32.c that has all the Windows-specific cruft
in it.
6. Tweak safe_strerror to deal with Windows sockets error codes.
I'm defenitely not thrilled by this tweak. You're only changing
"undocumented" into "winsock". I presume it helps with debugging this
stuff, but is it really worth the clutter it adds?
Sorry,
Mark
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 8:47 ` Mark Kettenis
@ 2005-03-26 17:38 ` Mark Mitchell
2005-03-26 17:48 ` Christopher Faylor
2005-03-27 12:59 ` Kai Henningsen
0 siblings, 2 replies; 9+ messages in thread
From: Mark Mitchell @ 2005-03-26 17:38 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
Thanks for the quick review.
> Here is a sumary of the changes in this patch:
>
> 1. Link with -lws2_32 on MinGW so we can use sockets.
>
> Can't you just use a standard autoconf check to check for that library
> instead of hardcoding it to be linked in on MinGW?
I could do that -- but I didn't because there are Windows configurations
that do not want to use Winsock. For example, we don't want to link in
this library on Cygwin; we just want to let the Cygwin DLL take care of
things.
> 2. In defs.h, define WINAPI so that source files know whether they are
> supposed to use the Windows API.
>
> This is bad. Yet another #ifdef WINDHOOS when we really are trying to
> get rid of those.
This is the same problem as above; I could autoconf things for Windows,
but those autoconf tests would fire under Cygwin as well.
> 3. Move ser_unix_readchar and friends (which were only barely
> UNIX-specific) into ser-base.c, renaming appropriately.
>
> Fair enough.
>
> 4. Add a new member (read_prim) to struct serial_ops, and use it from
> ser_base_readchar. The reason for this is that sockets must be
> read with "recv" on Windows; plain "read" does not work. So, we
> need a way to indicate which low-level primitive to use to read
> from a file descriptor.
>
> But write(2) does work and you don't need to use send(2). Oh you do
> but things are not quite symmetric. Could you fix that?
I'm not sure what you mean. Do you mean that you would like to create
write_prim, and use that from the high-level serial "write" function?
Sure, I can do that.
> Isn't it a
> better idea to change the #ifdef WINAPI in a #ifdef HAVE_RECV, add an
> autoconf check for recv(2), and always prefer it over read(2) if
> available for reading from a socket?
I was confused about that. I thought that using recv would not work as
well as read on UNIX, but I've done some extra research, and I think
send/recv should work fine everywhere. Please consider the change you
suggest made.
> 5. Make a handful of minor changes to ter-tcp.c to account for
> differences in the BSD and Windows sockets APIs.
>
> You mean that Windows doesn't have the proper BSD socket API even
> though Microsoft stole^Wused the BSD TCP stack?
Yes, there are a few minor differences.
> I really think these changes are too pervasive and that you really
> need to create a ser-win32.c that has all the Windows-specific cruft
> in it.
I can do that.
However, after making the changes you suggest above, there will only be
the following Windows-specific changes:
1. Macro definitions at top-of-file to unify the Windows/UNIX spellings
of ETIMEDOUT, closesocket, and ioctlsocket.
2. The change top net_open to use a "u_long *" argument as the last
argument to ioctl, rather than an "int *". (We could avoid the #ifdef
with a typedef at the top of the file, if that's better than the way I
have it now.)
3. The change to net_open to use WSAGetLastError() instead of errno on
Windows.
4. The change to _initialize_ser_tcp to initialize the sockets library.
To me, it seems a shame to duplicate the entire file (in particular,
net_open, which is the meat of the file) on account of these
differences. That function is mostly platform independent, including
parsing the host/port specification, setting up the socket, connecting
the socket, interacting with the UI during the connection delay, etc.
Would you please tell me definitively that you want this copied to
another file? I'm perfectly willing to do it, but I want to make sure
that it's really the right thing before I do. Or, perhaps you mean that
you want hooks inserted at all the right places, and overridden in
ser-win32.c? I can also do that, but I think it will make the code
harder to read. Please let me know.
> 6. Tweak safe_strerror to deal with Windows sockets error codes.
>
> I'm defenitely not thrilled by this tweak. You're only changing
> "undocumented" into "winsock". I presume it helps with debugging this
> stuff, but is it really worth the clutter it adds?
I think so, yes. Windows strerror never returns NULL. For unknown
values, it returns "Unknown error" with no indication of *which* unknown
error. These errors are presented to users, so, if for example, a
socket cannot be connected because the user entered the wrong port, or
gdbserver is not running, the user would only see "Unknown error". I
agree that, from a user-experience point of view, "winsock error 12345"
is not all that helpful -- but at least there is *some* method for
figuring out what went wrong.
Thanks,
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 17:38 ` Mark Mitchell
@ 2005-03-26 17:48 ` Christopher Faylor
2005-03-26 19:06 ` Mark Mitchell
2005-03-27 12:59 ` Kai Henningsen
1 sibling, 1 reply; 9+ messages in thread
From: Christopher Faylor @ 2005-03-26 17:48 UTC (permalink / raw)
To: Mark Mitchell, gdb-patches
On Sat, Mar 26, 2005 at 09:38:15AM -0800, Mark Mitchell wrote:
>Thanks for the quick review.
>
>> Here is a sumary of the changes in this patch:
>>
>> 1. Link with -lws2_32 on MinGW so we can use sockets.
>>
>>Can't you just use a standard autoconf check to check for that library
>>instead of hardcoding it to be linked in on MinGW?
>
>I could do that -- but I didn't because there are Windows configurations
>that do not want to use Winsock. For example, we don't want to link in
>this library on Cygwin; we just want to let the Cygwin DLL take care of
>things.
>
>> 2. In defs.h, define WINAPI so that source files know whether they are
>> supposed to use the Windows API.
>>
>>This is bad. Yet another #ifdef WINDHOOS when we really are trying to
>>get rid of those.
>
>This is the same problem as above; I could autoconf things for Windows,
>but those autoconf tests would fire under Cygwin as well.
I guess you could only check for the existence of ws2_32 when the host
is mingw, but that seems sort of redundant given that there is a
preprocessor test which precisely tells what needs to be done. While
I'm normally a big fan of using conditionals like "HAVE_WINSOCK", it
doesn't seem like it makes the code any clearer to use these types of
conditionals in this case unless we really anticipate that there will
be another OS out there with some of the pecularities os Windows but
not all of them.
One observation is that maybe you could do something like:
#if defined (__WIN32__) && !defined (__CYGWIN__)
# define MINGW
#endif
and use #ifdef MINGW where appropriate.
cgf
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 17:48 ` Christopher Faylor
@ 2005-03-26 19:06 ` Mark Mitchell
2005-03-26 21:03 ` Christopher Faylor
2005-03-26 22:00 ` Eli Zaretskii
0 siblings, 2 replies; 9+ messages in thread
From: Mark Mitchell @ 2005-03-26 19:06 UTC (permalink / raw)
To: Christopher Faylor; +Cc: gdb-patches
Christopher Faylor wrote:
> I guess you could only check for the existence of ws2_32 when the host
> is mingw, but that seems sort of redundant given that there is a
> preprocessor test which precisely tells what needs to be done.
Right.
> While
> I'm normally a big fan of using conditionals like "HAVE_WINSOCK", it
> doesn't seem like it makes the code any clearer to use these types of
> conditionals in this case unless we really anticipate that there will
> be another OS out there with some of the pecularities os Windows but
> not all of them.
>
> One observation is that maybe you could do something like:
>
> #if defined (__WIN32__) && !defined (__CYGWIN__)
> # define MINGW
> #endif
>
> and use #ifdef MINGW where appropriate.
If people would prefer that to WINAPI, that's fine by me.
(I'm not quite sure what we would call an environment in which the
compiler was Visual C, or some other non-GCC Windows compiler. Would
that still be MinGW? If not, then MINGW might not be as good a name,
which is why I went with WINAPI. But, I'm not concerned about how to
spell the conditional; whatever seems best to people is fine with me!)
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 19:06 ` Mark Mitchell
@ 2005-03-26 21:03 ` Christopher Faylor
2005-03-26 22:00 ` Eli Zaretskii
1 sibling, 0 replies; 9+ messages in thread
From: Christopher Faylor @ 2005-03-26 21:03 UTC (permalink / raw)
To: Mark Mitchell, gdb-patches
On Sat, Mar 26, 2005 at 11:06:03AM -0800, Mark Mitchell wrote:
>Christopher Faylor wrote:
>>While I'm normally a big fan of using conditionals like "HAVE_WINSOCK",
>>it doesn't seem like it makes the code any clearer to use these types
>>of conditionals in this case unless we really anticipate that there
>>will be another OS out there with some of the pecularities os Windows
>>but not all of them.
>>
>>One observation is that maybe you could do something like:
>>
>>#if defined (__WIN32__) && !defined (__CYGWIN__) # define MINGW #endif
>>
>>and use #ifdef MINGW where appropriate.
>
>If people would prefer that to WINAPI, that's fine by me.
>
>(I'm not quite sure what we would call an environment in which the
>compiler was Visual C, or some other non-GCC Windows compiler. Would
>that still be MinGW? If not, then MINGW might not be as good a name,
>which is why I went with WINAPI. But, I'm not concerned about how to
>spell the conditional; whatever seems best to people is fine with me!)
Huh. I don't know. I didn't even consider that gdb would build with
Visual C.
Actually, for the last four or five years, Cygwin's gcc hasn't defined
__WIN32__, so just using __WIN32__ would probably be sufficient.
Otherwise, I guess you're right, WINAPI makes the most sense.
cgf
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 19:06 ` Mark Mitchell
2005-03-26 21:03 ` Christopher Faylor
@ 2005-03-26 22:00 ` Eli Zaretskii
1 sibling, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2005-03-26 22:00 UTC (permalink / raw)
To: Mark Mitchell; +Cc: me, gdb-patches
> Date: Sat, 26 Mar 2005 11:06:03 -0800
> From: Mark Mitchell <mark@codesourcery.com>
> CC: gdb-patches@sources.redhat.com
>
> (I'm not quite sure what we would call an environment in which the
> compiler was Visual C, or some other non-GCC Windows compiler. Would
> that still be MinGW?
No. MinGW is the development environment that uses native Windows
ports of GNU tools. So using MSVC is out.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: Windows sockets
2005-03-26 17:38 ` Mark Mitchell
2005-03-26 17:48 ` Christopher Faylor
@ 2005-03-27 12:59 ` Kai Henningsen
1 sibling, 0 replies; 9+ messages in thread
From: Kai Henningsen @ 2005-03-27 12:59 UTC (permalink / raw)
To: gdb-patches
mark@codesourcery.com (Mark Mitchell) wrote on 26.03.05 in <42459E07.9020201@codesourcery.com>:
> > 6. Tweak safe_strerror to deal with Windows sockets error codes.
> >
> > I'm defenitely not thrilled by this tweak. You're only changing
> > "undocumented" into "winsock". I presume it helps with debugging this
> > stuff, but is it really worth the clutter it adds?
>
> I think so, yes. Windows strerror never returns NULL. For unknown
> values, it returns "Unknown error" with no indication of *which* unknown
> error. These errors are presented to users, so, if for example, a
> socket cannot be connected because the user entered the wrong port, or
> gdbserver is not running, the user would only see "Unknown error". I
> agree that, from a user-experience point of view, "winsock error 12345"
> is not all that helpful -- but at least there is *some* method for
> figuring out what went wrong.
Well ...
There *is* support in Win32 for getting error message text for OS error
numbers (which are completely different from errno numbers). There's a
slight complication in that until lately, these didn't cover Winsock
codes, but on modern Windows versions they do.
So it might make sense to try that.
See <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
debug/base/retrieving_the_last_error_code.asp> for example code.
MfG Kai
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-03-27 12:59 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-26 1:27 PATCH: Windows sockets Mark Mitchell
2005-03-26 2:09 ` Christopher Faylor
2005-03-26 8:47 ` Mark Kettenis
2005-03-26 17:38 ` Mark Mitchell
2005-03-26 17:48 ` Christopher Faylor
2005-03-26 19:06 ` Mark Mitchell
2005-03-26 21:03 ` Christopher Faylor
2005-03-26 22:00 ` Eli Zaretskii
2005-03-27 12:59 ` Kai Henningsen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox