* configure.tgt: Mark v850 as multi-arched.
[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>
0cf3e697
MH
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
c906108c
SS
35#include <sys/time.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <netdb.h>
39#include <sys/socket.h>
c906108c 40#include <netinet/tcp.h>
9db8d71f 41#include <netinet/udp.h>
c906108c 42
042be3a9 43#include <signal.h>
c906108c
SS
44#include "gdb_string.h"
45
9db8d71f
DJ
46static int net_open (struct serial *scb, const char *name);
47static void net_close (struct serial *scb);
7c7a201a 48extern int (*ui_loop_hook) (int);
c2c6d25f 49void _initialize_ser_tcp (void);
c906108c 50
7c7a201a
MH
51/* seconds to wait for connect */
52#define TIMEOUT 15
53/* how many times per second to poll ui_loop_hook */
54#define POLL_INTERVAL 2
55
56/* Open a tcp socket */
c906108c
SS
57
58static int
9db8d71f 59net_open (struct serial *scb, const char *name)
c906108c 60{
7c7a201a
MH
61 char *port_str, hostname[100];
62 int n, port, tmp;
9db8d71f 63 int use_udp;
c906108c
SS
64 struct hostent *hostent;
65 struct sockaddr_in sockaddr;
c906108c 66
9db8d71f
DJ
67 use_udp = 0;
68 if (strncmp (name, "udp:", 4) == 0)
69 {
70 use_udp = 1;
71 name = name + 4;
72 }
73 else if (strncmp (name, "tcp:", 4) == 0)
74 name = name + 4;
75
c906108c
SS
76 port_str = strchr (name, ':');
77
78 if (!port_str)
9db8d71f 79 error ("net_open: No colon in host name!"); /* Shouldn't ever happen */
c906108c
SS
80
81 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 82 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
83 hostname[tmp] = '\000'; /* Tie off host name */
84 port = atoi (port_str + 1);
85
7c7a201a 86 /* default hostname is localhost */
ad4571f3
CV
87 if (!hostname[0])
88 strcpy (hostname, "localhost");
89
c906108c 90 hostent = gethostbyname (hostname);
c906108c
SS
91 if (!hostent)
92 {
93 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
94 errno = ENOENT;
95 return -1;
96 }
97
9db8d71f
DJ
98 if (use_udp)
99 scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
100 else
101 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
102
7c7a201a
MH
103 if (scb->fd < 0)
104 return -1;
105
106 sockaddr.sin_family = PF_INET;
107 sockaddr.sin_port = htons (port);
108 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
109 sizeof (struct in_addr));
c906108c 110
7c7a201a
MH
111 /* set socket nonblocking */
112 tmp = 1;
113 ioctl (scb->fd, FIONBIO, &tmp);
c906108c 114
7c7a201a
MH
115 /* Use Non-blocking connect. connect() will return 0 if connected already. */
116 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
c906108c 117
7c7a201a
MH
118 if (n < 0 && errno != EINPROGRESS)
119 {
9db8d71f 120 net_close (scb);
7c7a201a 121 return -1;
c906108c
SS
122 }
123
7c7a201a
MH
124 if (n)
125 {
126 /* looks like we need to wait for the connect */
127 struct timeval t;
128 fd_set rset, wset;
129 int polls = 0;
130 FD_ZERO (&rset);
131
132 do
133 {
134 /* While we wait for the connect to complete
135 poll the UI so it can update or the user can
136 interrupt. */
137 if (ui_loop_hook)
138 {
139 if (ui_loop_hook (0))
140 {
141 errno = EINTR;
9db8d71f 142 net_close (scb);
7c7a201a
MH
143 return -1;
144 }
145 }
146
147 FD_SET (scb->fd, &rset);
148 wset = rset;
149 t.tv_sec = 0;
150 t.tv_usec = 1000000 / POLL_INTERVAL;
151
152 n = select (scb->fd + 1, &rset, &wset, NULL, &t);
153 polls++;
154 }
155 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
156 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
157 {
158 if (polls > TIMEOUT * POLL_INTERVAL)
159 errno = ETIMEDOUT;
9db8d71f 160 net_close (scb);
7c7a201a
MH
161 return -1;
162 }
163 }
c906108c 164
7c7a201a
MH
165 /* Got something. Is it an error? */
166 {
167 int res, err, len;
168 len = sizeof(err);
169 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
170 if (res < 0 || err)
171 {
172 if (err)
173 errno = err;
9db8d71f 174 net_close (scb);
7c7a201a
MH
175 return -1;
176 }
177 }
9db8d71f 178
7c7a201a
MH
179 /* turn off nonblocking */
180 tmp = 0;
181 ioctl (scb->fd, FIONBIO, &tmp);
182
9db8d71f
DJ
183 if (use_udp == 0)
184 {
185 /* Disable Nagle algorithm. Needed in some cases. */
186 tmp = 1;
187 setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
188 (char *)&tmp, sizeof (tmp));
189 }
190
7c7a201a
MH
191 /* If we don't do this, then GDB simply exits
192 when the remote side dies. */
193 signal (SIGPIPE, SIG_IGN);
c906108c
SS
194
195 return 0;
196}
197
c906108c 198static void
9db8d71f 199net_close (struct serial *scb)
c906108c
SS
200{
201 if (scb->fd < 0)
202 return;
203
c5aa993b 204 close (scb->fd);
c906108c
SS
205 scb->fd = -1;
206}
207
c906108c 208void
c2c6d25f 209_initialize_ser_tcp (void)
c906108c 210{
c2c6d25f
JM
211 struct serial_ops *ops = XMALLOC (struct serial_ops);
212 memset (ops, sizeof (struct serial_ops), 0);
213 ops->name = "tcp";
214 ops->next = 0;
9db8d71f
DJ
215 ops->open = net_open;
216 ops->close = net_close;
c2c6d25f
JM
217 ops->readchar = ser_unix_readchar;
218 ops->write = ser_unix_write;
219 ops->flush_output = ser_unix_nop_flush_output;
2acceee2 220 ops->flush_input = ser_unix_flush_input;
c2c6d25f
JM
221 ops->send_break = ser_unix_nop_send_break;
222 ops->go_raw = ser_unix_nop_raw;
223 ops->get_tty_state = ser_unix_nop_get_tty_state;
224 ops->set_tty_state = ser_unix_nop_set_tty_state;
225 ops->print_tty_state = ser_unix_nop_print_tty_state;
226 ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
227 ops->setbaudrate = ser_unix_nop_setbaudrate;
228 ops->setstopbits = ser_unix_nop_setstopbits;
229 ops->drain_output = ser_unix_nop_drain_output;
230 ops->async = ser_unix_async;
231 serial_add_interface (ops);
c906108c 232}
This page took 0.21704 seconds and 4 git commands to generate.