Cleanup ui-out table impl. Add struct ui_out_table. Rename
[deliverable/binutils-gdb.git] / gdb / ser-tcp.c
CommitLineData
c906108c 1/* Serial interface for raw TCP connections on Un*x like systems
b6ba6518
KB
2 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "defs.h"
23#include "serial.h"
c2c6d25f
JM
24#include "ser-unix.h"
25
c906108c 26#include <sys/types.h>
7c7a201a 27#include <sys/ioctl.h>
c906108c
SS
28#include <sys/time.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
31#include <netdb.h>
32#include <sys/socket.h>
c906108c 33#include <netinet/tcp.h>
c906108c 34
042be3a9 35#include <signal.h>
c906108c
SS
36#include "gdb_string.h"
37
819cc324
AC
38static int tcp_open (struct serial *scb, const char *name);
39static void tcp_close (struct serial *scb);
7c7a201a 40extern int (*ui_loop_hook) (int);
c2c6d25f 41void _initialize_ser_tcp (void);
c906108c 42
7c7a201a
MH
43/* seconds to wait for connect */
44#define TIMEOUT 15
45/* how many times per second to poll ui_loop_hook */
46#define POLL_INTERVAL 2
47
48/* Open a tcp socket */
c906108c
SS
49
50static int
819cc324 51tcp_open (struct serial *scb, const char *name)
c906108c 52{
7c7a201a
MH
53 char *port_str, hostname[100];
54 int n, port, tmp;
c906108c
SS
55 struct hostent *hostent;
56 struct sockaddr_in sockaddr;
c906108c
SS
57
58 port_str = strchr (name, ':');
59
60 if (!port_str)
7c7a201a 61 error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
c906108c
SS
62
63 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 64 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
65 hostname[tmp] = '\000'; /* Tie off host name */
66 port = atoi (port_str + 1);
67
7c7a201a 68 /* default hostname is localhost */
ad4571f3
CV
69 if (!hostname[0])
70 strcpy (hostname, "localhost");
71
c906108c 72 hostent = gethostbyname (hostname);
c906108c
SS
73 if (!hostent)
74 {
75 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
76 errno = ENOENT;
77 return -1;
78 }
79
7c7a201a
MH
80 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
81 if (scb->fd < 0)
82 return -1;
83
84 sockaddr.sin_family = PF_INET;
85 sockaddr.sin_port = htons (port);
86 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
87 sizeof (struct in_addr));
c906108c 88
7c7a201a
MH
89 /* set socket nonblocking */
90 tmp = 1;
91 ioctl (scb->fd, FIONBIO, &tmp);
c906108c 92
7c7a201a
MH
93 /* Use Non-blocking connect. connect() will return 0 if connected already. */
94 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
c906108c 95
7c7a201a
MH
96 if (n < 0 && errno != EINPROGRESS)
97 {
98 tcp_close (scb);
99 return -1;
c906108c
SS
100 }
101
7c7a201a
MH
102 if (n)
103 {
104 /* looks like we need to wait for the connect */
105 struct timeval t;
106 fd_set rset, wset;
107 int polls = 0;
108 FD_ZERO (&rset);
109
110 do
111 {
112 /* While we wait for the connect to complete
113 poll the UI so it can update or the user can
114 interrupt. */
115 if (ui_loop_hook)
116 {
117 if (ui_loop_hook (0))
118 {
119 errno = EINTR;
120 tcp_close (scb);
121 return -1;
122 }
123 }
124
125 FD_SET (scb->fd, &rset);
126 wset = rset;
127 t.tv_sec = 0;
128 t.tv_usec = 1000000 / POLL_INTERVAL;
129
130 n = select (scb->fd + 1, &rset, &wset, NULL, &t);
131 polls++;
132 }
133 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
134 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
135 {
136 if (polls > TIMEOUT * POLL_INTERVAL)
137 errno = ETIMEDOUT;
138 tcp_close (scb);
139 return -1;
140 }
141 }
c906108c 142
7c7a201a
MH
143 /* Got something. Is it an error? */
144 {
145 int res, err, len;
146 len = sizeof(err);
147 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
148 if (res < 0 || err)
149 {
150 if (err)
151 errno = err;
152 tcp_close (scb);
153 return -1;
154 }
155 }
156
157 /* turn off nonblocking */
158 tmp = 0;
159 ioctl (scb->fd, FIONBIO, &tmp);
160
161 /* If we don't do this, then GDB simply exits
162 when the remote side dies. */
163 signal (SIGPIPE, SIG_IGN);
c906108c
SS
164
165 return 0;
166}
167
c906108c 168static void
819cc324 169tcp_close (struct serial *scb)
c906108c
SS
170{
171 if (scb->fd < 0)
172 return;
173
c5aa993b 174 close (scb->fd);
c906108c
SS
175 scb->fd = -1;
176}
177
c906108c 178void
c2c6d25f 179_initialize_ser_tcp (void)
c906108c 180{
c2c6d25f
JM
181 struct serial_ops *ops = XMALLOC (struct serial_ops);
182 memset (ops, sizeof (struct serial_ops), 0);
183 ops->name = "tcp";
184 ops->next = 0;
185 ops->open = tcp_open;
186 ops->close = tcp_close;
187 ops->readchar = ser_unix_readchar;
188 ops->write = ser_unix_write;
189 ops->flush_output = ser_unix_nop_flush_output;
2acceee2 190 ops->flush_input = ser_unix_flush_input;
c2c6d25f
JM
191 ops->send_break = ser_unix_nop_send_break;
192 ops->go_raw = ser_unix_nop_raw;
193 ops->get_tty_state = ser_unix_nop_get_tty_state;
194 ops->set_tty_state = ser_unix_nop_set_tty_state;
195 ops->print_tty_state = ser_unix_nop_print_tty_state;
196 ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
197 ops->setbaudrate = ser_unix_nop_setbaudrate;
198 ops->setstopbits = ser_unix_nop_setstopbits;
199 ops->drain_output = ser_unix_nop_drain_output;
200 ops->async = ser_unix_async;
201 serial_add_interface (ops);
c906108c 202}
This page took 0.160437 seconds and 4 git commands to generate.