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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [ser-tcp.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 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, 2009, 2010 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
#include "gdbcmd.h"
26
#include "cli/cli-decode.h"
27
#include "cli/cli-setshow.h"
28
 
29
#include <sys/types.h>
30
 
31
#ifdef HAVE_SYS_FILIO_H
32
#include <sys/filio.h>  /* For FIONBIO. */
33
#endif
34
#ifdef HAVE_SYS_IOCTL_H
35
#include <sys/ioctl.h>  /* For FIONBIO. */
36
#endif
37
 
38
#include <sys/time.h>
39
 
40
#ifdef USE_WIN32API
41
#include <winsock2.h>
42
#define ETIMEDOUT WSAETIMEDOUT
43
#define close(fd) closesocket (fd)
44
#define ioctl ioctlsocket
45
#else
46
#include <netinet/in.h>
47
#include <arpa/inet.h>
48
#include <netdb.h>
49
#include <sys/socket.h>
50
#include <netinet/tcp.h>
51
#endif
52
 
53
#include <signal.h>
54
#include "gdb_string.h"
55
#include "gdb_select.h"
56
 
57
#ifndef HAVE_SOCKLEN_T
58
typedef int socklen_t;
59
#endif
60
 
61
void _initialize_ser_tcp (void);
62
 
63
/* For "set tcp" and "show tcp".  */
64
 
65
static struct cmd_list_element *tcp_set_cmdlist;
66
static struct cmd_list_element *tcp_show_cmdlist;
67
 
68
/* Whether to auto-retry refused connections.  */
69
 
70
static int tcp_auto_retry = 1;
71
 
72
/* Timeout period for connections, in seconds.  */
73
 
74
static int tcp_retry_limit = 15;
75
 
76
/* how many times per second to poll deprecated_ui_loop_hook */
77
 
78
#define POLL_INTERVAL 5
79
 
80
/* Helper function to wait a while.  If SCB is non-null, wait on its
81
   file descriptor.  Otherwise just wait on a timeout, updating *POLLS.
82
   Returns -1 on timeout or interrupt, otherwise the value of select.  */
83
 
84
static int
85
wait_for_connect (struct serial *scb, int *polls)
86
{
87
  struct timeval t;
88
  int n;
89
 
90
  /* While we wait for the connect to complete,
91
     poll the UI so it can update or the user can
92
     interrupt.  */
93
  if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
94
    {
95
      errno = EINTR;
96
      return -1;
97
    }
98
 
99
  /* Check for timeout.  */
100
  if (*polls > tcp_retry_limit * POLL_INTERVAL)
101
    {
102
      errno = ETIMEDOUT;
103
      return -1;
104
    }
105
 
106
  /* Back off to polling once per second after the first POLL_INTERVAL
107
     polls.  */
108
  if (*polls < POLL_INTERVAL)
109
    {
110
      t.tv_sec = 0;
111
      t.tv_usec = 1000000 / POLL_INTERVAL;
112
    }
113
  else
114
    {
115
      t.tv_sec = 1;
116
      t.tv_usec = 0;
117
    }
118
 
119
  if (scb)
120
    {
121
      fd_set rset, wset, eset;
122
      FD_ZERO (&rset);
123
      FD_SET (scb->fd, &rset);
124
      wset = rset;
125
      eset = rset;
126
 
127
      /* POSIX systems return connection success or failure by signalling
128
         wset.  Windows systems return success in wset and failure in
129
         eset.
130
 
131
         We must call select here, rather than gdb_select, because
132
         the serial structure has not yet been initialized - the
133
         MinGW select wrapper will not know that this FD refers
134
         to a socket.  */
135
      n = select (scb->fd + 1, &rset, &wset, &eset, &t);
136
    }
137
  else
138
    /* Use gdb_select here, since we have no file descriptors, and on
139
       Windows, plain select doesn't work in that case.  */
140
    n = gdb_select (0, NULL, NULL, NULL, &t);
141
 
142
  /* If we didn't time out, only count it as one poll.  */
143
  if (n > 0 || *polls < POLL_INTERVAL)
144
    (*polls)++;
145
  else
146
    (*polls) += POLL_INTERVAL;
147
 
148
  return n;
149
}
150
 
151
/* Open a tcp socket */
152
 
153
int
154
net_open (struct serial *scb, const char *name)
155
{
156
  char *port_str, hostname[100];
157
  int n, port, tmp;
158
  int use_udp;
159
  struct hostent *hostent;
160
  struct sockaddr_in sockaddr;
161
#ifdef USE_WIN32API
162
  u_long ioarg;
163
#else
164
  int ioarg;
165
#endif
166
  int polls = 0;
167
 
168
  use_udp = 0;
169
  if (strncmp (name, "udp:", 4) == 0)
170
    {
171
      use_udp = 1;
172
      name = name + 4;
173
    }
174
  else if (strncmp (name, "tcp:", 4) == 0)
175
    name = name + 4;
176
 
177
  port_str = strchr (name, ':');
178
 
179
  if (!port_str)
180
    error (_("net_open: No colon in host name!"));         /* Shouldn't ever happen */
181
 
182
  tmp = min (port_str - name, (int) sizeof hostname - 1);
183
  strncpy (hostname, name, tmp);        /* Don't want colon */
184
  hostname[tmp] = '\000';       /* Tie off host name */
185
  port = atoi (port_str + 1);
186
 
187
  /* default hostname is localhost */
188
  if (!hostname[0])
189
    strcpy (hostname, "localhost");
190
 
191
  hostent = gethostbyname (hostname);
192
  if (!hostent)
193
    {
194
      fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
195
      errno = ENOENT;
196
      return -1;
197
    }
198
 
199
  sockaddr.sin_family = PF_INET;
200
  sockaddr.sin_port = htons (port);
201
  memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
202
          sizeof (struct in_addr));
203
 
204
 retry:
205
 
206
  if (use_udp)
207
    scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
208
  else
209
    scb->fd = socket (PF_INET, SOCK_STREAM, 0);
210
 
211
  if (scb->fd < 0)
212
    return -1;
213
 
214
  /* set socket nonblocking */
215
  ioarg = 1;
216
  ioctl (scb->fd, FIONBIO, &ioarg);
217
 
218
  /* Use Non-blocking connect.  connect() will return 0 if connected already. */
219
  n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
220
 
221
  if (n < 0)
222
    {
223
#ifdef USE_WIN32API
224
      int err = WSAGetLastError();
225
#else
226
      int err = errno;
227
#endif
228
 
229
      /* Maybe we're waiting for the remote target to become ready to
230
         accept connections.  */
231
      if (tcp_auto_retry
232
#ifdef USE_WIN32API
233
          && err == WSAECONNREFUSED
234
#else
235
          && err == ECONNREFUSED
236
#endif
237
          && wait_for_connect (NULL, &polls) >= 0)
238
        {
239
          close (scb->fd);
240
          goto retry;
241
        }
242
 
243
      if (
244
#ifdef USE_WIN32API
245
          /* Under Windows, calling "connect" with a non-blocking socket
246
             results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
247
          err != WSAEWOULDBLOCK
248
#else
249
          err != EINPROGRESS
250
#endif
251
          )
252
        {
253
          errno = err;
254
          net_close (scb);
255
          return -1;
256
        }
257
 
258
      /* looks like we need to wait for the connect */
259
      do
260
        {
261
          n = wait_for_connect (scb, &polls);
262
        }
263
      while (n == 0);
264
      if (n < 0)
265
        {
266
          net_close (scb);
267
          return -1;
268
        }
269
    }
270
 
271
  /* Got something.  Is it an error? */
272
  {
273
    int res, err;
274
    socklen_t len;
275
    len = sizeof (err);
276
    /* On Windows, the fourth parameter to getsockopt is a "char *";
277
       on UNIX systems it is generally "void *".  The cast to "void *"
278
       is OK everywhere, since in C "void *" can be implicitly
279
       converted to any pointer type.  */
280
    res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
281
    if (res < 0 || err)
282
      {
283
        /* Maybe the target still isn't ready to accept the connection.  */
284
        if (tcp_auto_retry
285
#ifdef USE_WIN32API
286
            && err == WSAECONNREFUSED
287
#else
288
            && err == ECONNREFUSED
289
#endif
290
            && wait_for_connect (NULL, &polls) >= 0)
291
          {
292
            close (scb->fd);
293
            goto retry;
294
          }
295
        if (err)
296
          errno = err;
297
        net_close (scb);
298
        return -1;
299
      }
300
  }
301
 
302
  /* turn off nonblocking */
303
  ioarg = 0;
304
  ioctl (scb->fd, FIONBIO, &ioarg);
305
 
306
  if (use_udp == 0)
307
    {
308
      /* Disable Nagle algorithm. Needed in some cases. */
309
      tmp = 1;
310
      setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
311
                  (char *)&tmp, sizeof (tmp));
312
    }
313
 
314
#ifdef SIGPIPE
315
  /* If we don't do this, then GDB simply exits
316
     when the remote side dies.  */
317
  signal (SIGPIPE, SIG_IGN);
318
#endif
319
 
320
  return 0;
321
}
322
 
323
void
324
net_close (struct serial *scb)
325
{
326
  if (scb->fd < 0)
327
    return;
328
 
329
  close (scb->fd);
330
  scb->fd = -1;
331
}
332
 
333
int
334
net_read_prim (struct serial *scb, size_t count)
335
{
336
  return recv (scb->fd, scb->buf, count, 0);
337
}
338
 
339
int
340
net_write_prim (struct serial *scb, const void *buf, size_t count)
341
{
342
  return send (scb->fd, buf, count, 0);
343
}
344
 
345
int
346
ser_tcp_send_break (struct serial *scb)
347
{
348
  /* Send telnet IAC and BREAK characters. */
349
  return (serial_write (scb, "\377\363", 2));
350
}
351
 
352
/* Support for "set tcp" and "show tcp" commands.  */
353
 
354
static void
355
set_tcp_cmd (char *args, int from_tty)
356
{
357
  help_list (tcp_set_cmdlist, "set tcp ", -1, gdb_stdout);
358
}
359
 
360
static void
361
show_tcp_cmd (char *args, int from_tty)
362
{
363
  help_list (tcp_show_cmdlist, "show tcp ", -1, gdb_stdout);
364
}
365
 
366
 
367
void
368
_initialize_ser_tcp (void)
369
{
370
#ifdef USE_WIN32API
371
  /* Do nothing; the TCP serial operations will be initialized in
372
     ser-mingw.c.  */
373
#else
374
  struct serial_ops *ops;
375
  ops = XMALLOC (struct serial_ops);
376
  memset (ops, 0, sizeof (struct serial_ops));
377
  ops->name = "tcp";
378
  ops->next = 0;
379
  ops->open = net_open;
380
  ops->close = net_close;
381
  ops->readchar = ser_base_readchar;
382
  ops->write = ser_base_write;
383
  ops->flush_output = ser_base_flush_output;
384
  ops->flush_input = ser_base_flush_input;
385
  ops->send_break = ser_tcp_send_break;
386
  ops->go_raw = ser_base_raw;
387
  ops->get_tty_state = ser_base_get_tty_state;
388
  ops->set_tty_state = ser_base_set_tty_state;
389
  ops->print_tty_state = ser_base_print_tty_state;
390
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
391
  ops->setbaudrate = ser_base_setbaudrate;
392
  ops->setstopbits = ser_base_setstopbits;
393
  ops->drain_output = ser_base_drain_output;
394
  ops->async = ser_base_async;
395
  ops->read_prim = net_read_prim;
396
  ops->write_prim = net_write_prim;
397
  serial_add_interface (ops);
398
#endif /* USE_WIN32API */
399
 
400
  add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
401
TCP protocol specific variables\n\
402
Configure variables specific to remote TCP connections"),
403
                  &tcp_set_cmdlist, "set tcp ",
404
 
405
  add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
406
TCP protocol specific variables\n\
407
Configure variables specific to remote TCP connections"),
408
                  &tcp_show_cmdlist, "show tcp ",
409
 
410
 
411
  add_setshow_boolean_cmd ("auto-retry", class_obscure,
412
                           &tcp_auto_retry, _("\
413
Set auto-retry on socket connect"), _("\
414
Show auto-retry on socket connect"),
415
                           NULL, NULL, NULL,
416
                           &tcp_set_cmdlist, &tcp_show_cmdlist);
417
 
418
  add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
419
                            &tcp_retry_limit, _("\
420
Set timeout limit for socket connection"), _("\
421
Show timeout limit for socket connection"),
422
                           NULL, NULL, NULL,
423
                           &tcp_set_cmdlist, &tcp_show_cmdlist);
424
}

powered by: WebSVN 2.1.0

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