aboutsummaryrefslogtreecommitdiff
path: root/gdb/ser-tcp.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-04-21 05:34:33 +0000
committerMark Mitchell <mark@codesourcery.com>2005-04-21 05:34:33 +0000
commitb450502905875e85aab17371f78bb6befe5a3059 (patch)
tree74c33d9db60a1f34eb7d4501a3d412e31c4628e8 /gdb/ser-tcp.c
parent20b26460df083b26399a8e0dfe385077833db7a7 (diff)
downloadgdb-b450502905875e85aab17371f78bb6befe5a3059.zip
gdb-b450502905875e85aab17371f78bb6befe5a3059.tar.gz
gdb-b450502905875e85aab17371f78bb6befe5a3059.tar.bz2
* configure.ac: On MinGW, define USE_WIN32API and link with
-lws2_32. * ser-tcp.c (<winsock2.h>): Include, for Windows. (ETIMEDOUT): Define, for Windows. (ioctl): Likewise. (closesocket): Define, for POSIX. (net_open): Adjust for differences in socket functions between Windows and UNIX. (net_close): Likweise. (net_read_prim): New function. (net_write_prim): Likewise. (_initialize_ser_tcp): Initialize winsock. Fill in read_prim and write_prim. * ser-unix.h (ser_unix_readcchar): Remove. (ser_unix_read_prim): Declare. (ser_unix_write_prim): Likewise. * ser-unix.c (generic_readchar): Move to ser-base.c. (ser_unix_wait_for): Likewise. (do_unix_readchar): Likewise. (ser_unix_readchar): Likewise. (_initialize_ser_hardwire): Initialize read_prim and write_prim. (ser_unix_read_prim): New function. (ser_unix_write_prim): Likewise. * ser-base.h (generic_readchar): Declare. (ser_base_readchar): Likewise. * ser-base.c (<winsock2.h>): Include, for windows. (fd_event): Use the read primitive specified by the serial interface. (ser_base_wait_for): Moved from ser-unix.c (do_ser_base_read_char): Likewise. (generic_readchar): Likewise. (ser_base_readchar): Likewise. (ser_base_write): Use the write primitive specified by the serial interface. * ser-pipe.c (_initialize_ser_pipe): Use ser_base_readchar, not ser_unix_readchar. Initialize read_prim and write_prim. * serial.c (struct serial_ops): Add read_prim and write_prim. * configure: Regenerate.
Diffstat (limited to 'gdb/ser-tcp.c')
-rw-r--r--gdb/ser-tcp.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index f908d25..abe6ed4 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);
}