OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [ser-tcp.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Serial interface for raw TCP connections on Un*x like systems.
2
 
3
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2005, 2006,
4
   2007, 2008 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "serial.h"
23
#include "ser-base.h"
24
#include "ser-tcp.h"
25
 
26
#include <sys/types.h>
27
 
28
#ifdef HAVE_SYS_FILIO_H
29
#include <sys/filio.h>  /* For FIONBIO. */
30
#endif
31
#ifdef HAVE_SYS_IOCTL_H
32
#include <sys/ioctl.h>  /* For FIONBIO. */
33
#endif
34
 
35
#include <sys/time.h>
36
 
37
#ifdef USE_WIN32API
38
#include <winsock2.h>
39
#define ETIMEDOUT WSAETIMEDOUT
40
#define close(fd) closesocket (fd)
41
#define ioctl ioctlsocket
42
#else
43
#include <netinet/in.h>
44
#include <arpa/inet.h>
45
#include <netdb.h>
46
#include <sys/socket.h>
47
#include <netinet/tcp.h>
48
#endif
49
 
50
#include <signal.h>
51
#include "gdb_string.h"
52
 
53
#ifndef HAVE_SOCKLEN_T
54
typedef int socklen_t;
55
#endif
56
 
57
void _initialize_ser_tcp (void);
58
 
59
/* seconds to wait for connect */
60
#define TIMEOUT 15
61
/* how many times per second to poll deprecated_ui_loop_hook */
62
#define POLL_INTERVAL 2
63
 
64
/* Open a tcp socket */
65
 
66
int
67
net_open (struct serial *scb, const char *name)
68
{
69
  char *port_str, hostname[100];
70
  int n, port, tmp;
71
  int use_udp;
72
  struct hostent *hostent;
73
  struct sockaddr_in sockaddr;
74
#ifdef USE_WIN32API
75
  u_long ioarg;
76
#else
77
  int ioarg;
78
#endif
79
 
80
  use_udp = 0;
81
  if (strncmp (name, "udp:", 4) == 0)
82
    {
83
      use_udp = 1;
84
      name = name + 4;
85
    }
86
  else if (strncmp (name, "tcp:", 4) == 0)
87
    name = name + 4;
88
 
89
  port_str = strchr (name, ':');
90
 
91
  if (!port_str)
92
    error (_("net_open: No colon in host name!"));         /* Shouldn't ever happen */
93
 
94
  tmp = min (port_str - name, (int) sizeof hostname - 1);
95
  strncpy (hostname, name, tmp);        /* Don't want colon */
96
  hostname[tmp] = '\000';       /* Tie off host name */
97
  port = atoi (port_str + 1);
98
 
99
  /* default hostname is localhost */
100
  if (!hostname[0])
101
    strcpy (hostname, "localhost");
102
 
103
  hostent = gethostbyname (hostname);
104
  if (!hostent)
105
    {
106
      fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
107
      errno = ENOENT;
108
      return -1;
109
    }
110
 
111
  if (use_udp)
112
    scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
113
  else
114
    scb->fd = socket (PF_INET, SOCK_STREAM, 0);
115
 
116
  if (scb->fd < 0)
117
    return -1;
118
 
119
  sockaddr.sin_family = PF_INET;
120
  sockaddr.sin_port = htons (port);
121
  memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
122
          sizeof (struct in_addr));
123
 
124
  /* set socket nonblocking */
125
  ioarg = 1;
126
  ioctl (scb->fd, FIONBIO, &ioarg);
127
 
128
  /* Use Non-blocking connect.  connect() will return 0 if connected already. */
129
  n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
130
 
131
  if (n < 0
132
#ifdef USE_WIN32API
133
      /* Under Windows, calling "connect" with a non-blocking socket
134
         results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
135
      && WSAGetLastError() != WSAEWOULDBLOCK
136
#else
137
      && errno != EINPROGRESS
138
#endif
139
      )
140
    {
141
#ifdef USE_WIN32API
142
      errno = WSAGetLastError();
143
#endif
144
      net_close (scb);
145
      return -1;
146
    }
147
 
148
  if (n)
149
    {
150
      /* looks like we need to wait for the connect */
151
      struct timeval t;
152
      fd_set rset, wset, eset;
153
      int polls = 0;
154
      FD_ZERO (&rset);
155
 
156
      do
157
        {
158
          /* While we wait for the connect to complete,
159
             poll the UI so it can update or the user can
160
             interrupt.  */
161
          if (deprecated_ui_loop_hook)
162
            {
163
              if (deprecated_ui_loop_hook (0))
164
                {
165
                  errno = EINTR;
166
                  net_close (scb);
167
                  return -1;
168
                }
169
            }
170
 
171
          FD_SET (scb->fd, &rset);
172
          wset = rset;
173
          eset = rset;
174
          t.tv_sec = 0;
175
          t.tv_usec = 1000000 / POLL_INTERVAL;
176
 
177
          /* POSIX systems return connection success or failure by signalling
178
             wset.  Windows systems return success in wset and failure in
179
             eset.
180
 
181
             We must call select here, rather than gdb_select, because
182
             the serial structure has not yet been initialized - the
183
             MinGW select wrapper will not know that this FD refers
184
             to a socket.  */
185
          n = select (scb->fd + 1, &rset, &wset, &eset, &t);
186
          polls++;
187
        }
188
      while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
189
      if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
190
        {
191
          if (polls > TIMEOUT * POLL_INTERVAL)
192
            errno = ETIMEDOUT;
193
          net_close (scb);
194
          return -1;
195
        }
196
    }
197
 
198
  /* Got something.  Is it an error? */
199
  {
200
    int res, err;
201
    socklen_t len;
202
    len = sizeof (err);
203
    /* On Windows, the fourth parameter to getsockopt is a "char *";
204
       on UNIX systems it is generally "void *".  The cast to "void *"
205
       is OK everywhere, since in C "void *" can be implicitly
206
       converted to any pointer type.  */
207
    res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
208
    if (res < 0 || err)
209
      {
210
        if (err)
211
          errno = err;
212
        net_close (scb);
213
        return -1;
214
      }
215
  }
216
 
217
  /* turn off nonblocking */
218
  ioarg = 0;
219
  ioctl (scb->fd, FIONBIO, &ioarg);
220
 
221
  if (use_udp == 0)
222
    {
223
      /* Disable Nagle algorithm. Needed in some cases. */
224
      tmp = 1;
225
      setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
226
                  (char *)&tmp, sizeof (tmp));
227
    }
228
 
229
#ifdef SIGPIPE
230
  /* If we don't do this, then GDB simply exits
231
     when the remote side dies.  */
232
  signal (SIGPIPE, SIG_IGN);
233
#endif
234
 
235
  return 0;
236
}
237
 
238
void
239
net_close (struct serial *scb)
240
{
241
  if (scb->fd < 0)
242
    return;
243
 
244
  close (scb->fd);
245
  scb->fd = -1;
246
}
247
 
248
int
249
net_read_prim (struct serial *scb, size_t count)
250
{
251
  return recv (scb->fd, scb->buf, count, 0);
252
}
253
 
254
int
255
net_write_prim (struct serial *scb, const void *buf, size_t count)
256
{
257
  return send (scb->fd, buf, count, 0);
258
}
259
 
260
void
261
_initialize_ser_tcp (void)
262
{
263
#ifdef USE_WIN32API
264
  /* Do nothing; the TCP serial operations will be initialized in
265
     ser-mingw.c.  */
266
  return;
267
#else
268
  struct serial_ops *ops;
269
  ops = XMALLOC (struct serial_ops);
270
  memset (ops, 0, sizeof (struct serial_ops));
271
  ops->name = "tcp";
272
  ops->next = 0;
273
  ops->open = net_open;
274
  ops->close = net_close;
275
  ops->readchar = ser_base_readchar;
276
  ops->write = ser_base_write;
277
  ops->flush_output = ser_base_flush_output;
278
  ops->flush_input = ser_base_flush_input;
279
  ops->send_break = ser_base_send_break;
280
  ops->go_raw = ser_base_raw;
281
  ops->get_tty_state = ser_base_get_tty_state;
282
  ops->set_tty_state = ser_base_set_tty_state;
283
  ops->print_tty_state = ser_base_print_tty_state;
284
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
285
  ops->setbaudrate = ser_base_setbaudrate;
286
  ops->setstopbits = ser_base_setstopbits;
287
  ops->drain_output = ser_base_drain_output;
288
  ops->async = ser_base_async;
289
  ops->read_prim = net_read_prim;
290
  ops->write_prim = net_write_prim;
291
  serial_add_interface (ops);
292
#endif /* USE_WIN32API */
293
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.