diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-04-21 05:34:33 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 2005-04-21 05:34:33 +0000 |
commit | b450502905875e85aab17371f78bb6befe5a3059 (patch) | |
tree | 74c33d9db60a1f34eb7d4501a3d412e31c4628e8 /gdb/ser-tcp.c | |
parent | 20b26460df083b26399a8e0dfe385077833db7a7 (diff) | |
download | gdb-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.c | 65 |
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); } |