* hppa-tdep.h (hppa_in_solib_call_trampoline)
[deliverable/binutils-gdb.git] / gdb / ser-tcp.c
index f908d258b5f8564e20accfa6a73b304d30ae7445..aed91c27654dcb792ba130e11a6196c4db05ef75 100644 (file)
@@ -1,5 +1,6 @@
-/* Serial interface for raw TCP connections on Un*x like systems
-   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001
+/* Serial interface for raw TCP connections on Un*x like systems.
+
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -16,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "serial.h"
 #endif
 
 #include <sys/time.h>
+
+#ifdef USE_WIN32API
+#include <winsock2.h>
+#define ETIMEDOUT WSAETIMEDOUT
+#define close(fd) closesocket (fd)
+#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"
 
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
 static int net_open (struct serial *scb, const char *name);
 static void net_close (struct serial *scb);
 void _initialize_ser_tcp (void);
@@ -62,6 +75,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 +126,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;
     }
@@ -163,9 +192,14 @@ net_open (struct serial *scb, const char *name)
 
   /* Got something.  Is it an error? */
   {
-    int res, err, len;
+    int res, err;
+    socklen_t 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 +210,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 +240,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 +282,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);
 }
This page took 0.025353 seconds and 4 git commands to generate.