diff options
Diffstat (limited to 'gdb/ser-tcp.c')
-rw-r--r-- | gdb/ser-tcp.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c index f908d258b5f..abe6ed4a35b 100644 --- a/gdb/ser-tcp.c +++ b/gdb/ser-tcp.c @@ -34,11 +34,19 @@ #endif #include <sys/time.h> + +#ifdef USE_WIN32API +#include <winsock2.h> +#define ETIMEDOUT WSAETIMEDOUT +#define close closesocket +#define ioctl ioctlsocket +#else #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/tcp.h> +#endif #include <signal.h> #include "gdb_string.h" @@ -62,6 +70,11 @@ net_open (struct serial *scb, const char *name) int use_udp; struct hostent *hostent; struct sockaddr_in sockaddr; +#ifdef USE_WIN32API + u_long ioarg; +#else + int ioarg; +#endif use_udp = 0; if (strncmp (name, "udp:", 4) == 0) @@ -108,14 +121,25 @@ net_open (struct serial *scb, const char *name) sizeof (struct in_addr)); /* set socket nonblocking */ - tmp = 1; - ioctl (scb->fd, FIONBIO, &tmp); + ioarg = 1; + ioctl (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 && errno != EINPROGRESS) + if (n < 0 +#ifdef USE_WIN32API + /* Under Windows, calling "connect" with a non-blocking socket + results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */ + && WSAGetLastError() != WSAEWOULDBLOCK +#else + && errno != EINPROGRESS +#endif + ) { +#ifdef USE_WIN32API + errno = WSAGetLastError(); +#endif net_close (scb); return -1; } @@ -165,7 +189,11 @@ net_open (struct serial *scb, const char *name) { int res, err, len; len = sizeof(err); - res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len); + /* 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) @@ -176,8 +204,8 @@ net_open (struct serial *scb, const char *name) } /* turn off nonblocking */ - tmp = 0; - ioctl (scb->fd, FIONBIO, &tmp); + ioarg = 0; + ioctl (scb->fd, FIONBIO, &ioarg); if (use_udp == 0) { @@ -206,16 +234,35 @@ net_close (struct serial *scb) scb->fd = -1; } +static int +net_read_prim (struct serial *scb, size_t count) +{ + return recv (scb->fd, scb->buf, count, 0); +} + +static int +net_write_prim (struct serial *scb, const void *buf, size_t count) +{ + return send (scb->fd, buf, count, 0); +} + void _initialize_ser_tcp (void) { - struct serial_ops *ops = XMALLOC (struct serial_ops); + struct serial_ops *ops; +#ifdef USE_WIN32API + 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_unix_readchar; + ops->readchar = ser_base_readchar; ops->write = ser_base_write; ops->flush_output = ser_base_flush_output; ops->flush_input = ser_base_flush_input; @@ -229,5 +276,7 @@ _initialize_ser_tcp (void) ops->setstopbits = ser_base_setstopbits; ops->drain_output = ser_base_drain_output; ops->async = ser_base_async; + ops->read_prim = net_read_prim; + ops->write_prim = net_write_prim; serial_add_interface (ops); } |