]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-tcp.c
* dwarf2-frame.h: Update copyrigh year.
[thirdparty/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>
c906108c 41
042be3a9 42#include <signal.h>
c906108c
SS
43#include "gdb_string.h"
44
9db8d71f
DJ
45static int net_open (struct serial *scb, const char *name);
46static void net_close (struct serial *scb);
c2c6d25f 47void _initialize_ser_tcp (void);
c906108c 48
7c7a201a
MH
49/* seconds to wait for connect */
50#define TIMEOUT 15
98bbd631 51/* how many times per second to poll deprecated_ui_loop_hook */
7c7a201a
MH
52#define POLL_INTERVAL 2
53
54/* Open a tcp socket */
c906108c
SS
55
56static int
9db8d71f 57net_open (struct serial *scb, const char *name)
c906108c 58{
7c7a201a
MH
59 char *port_str, hostname[100];
60 int n, port, tmp;
9db8d71f 61 int use_udp;
c906108c
SS
62 struct hostent *hostent;
63 struct sockaddr_in sockaddr;
c906108c 64
9db8d71f
DJ
65 use_udp = 0;
66 if (strncmp (name, "udp:", 4) == 0)
67 {
68 use_udp = 1;
69 name = name + 4;
70 }
71 else if (strncmp (name, "tcp:", 4) == 0)
72 name = name + 4;
73
c906108c
SS
74 port_str = strchr (name, ':');
75
76 if (!port_str)
8a3fe4f8 77 error (_("net_open: No colon in host name!")); /* Shouldn't ever happen */
c906108c
SS
78
79 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 80 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
81 hostname[tmp] = '\000'; /* Tie off host name */
82 port = atoi (port_str + 1);
83
7c7a201a 84 /* default hostname is localhost */
ad4571f3
CV
85 if (!hostname[0])
86 strcpy (hostname, "localhost");
87
c906108c 88 hostent = gethostbyname (hostname);
c906108c
SS
89 if (!hostent)
90 {
91 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
92 errno = ENOENT;
93 return -1;
94 }
95
9db8d71f
DJ
96 if (use_udp)
97 scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
98 else
99 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
100
7c7a201a
MH
101 if (scb->fd < 0)
102 return -1;
103
104 sockaddr.sin_family = PF_INET;
105 sockaddr.sin_port = htons (port);
106 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
107 sizeof (struct in_addr));
c906108c 108
7c7a201a
MH
109 /* set socket nonblocking */
110 tmp = 1;
111 ioctl (scb->fd, FIONBIO, &tmp);
c906108c 112
7c7a201a
MH
113 /* Use Non-blocking connect. connect() will return 0 if connected already. */
114 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
c906108c 115
7c7a201a
MH
116 if (n < 0 && errno != EINPROGRESS)
117 {
9db8d71f 118 net_close (scb);
7c7a201a 119 return -1;
c906108c
SS
120 }
121
7c7a201a
MH
122 if (n)
123 {
124 /* looks like we need to wait for the connect */
125 struct timeval t;
126 fd_set rset, wset;
127 int polls = 0;
128 FD_ZERO (&rset);
129
130 do
131 {
2c1ab592 132 /* While we wait for the connect to complete,
7c7a201a 133 poll the UI so it can update or the user can
2c1ab592 134 interrupt. */
98bbd631 135 if (deprecated_ui_loop_hook)
7c7a201a 136 {
98bbd631 137 if (deprecated_ui_loop_hook (0))
7c7a201a
MH
138 {
139 errno = EINTR;
9db8d71f 140 net_close (scb);
7c7a201a
MH
141 return -1;
142 }
143 }
144
145 FD_SET (scb->fd, &rset);
146 wset = rset;
147 t.tv_sec = 0;
148 t.tv_usec = 1000000 / POLL_INTERVAL;
149
150 n = select (scb->fd + 1, &rset, &wset, NULL, &t);
151 polls++;
152 }
153 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
154 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
155 {
156 if (polls > TIMEOUT * POLL_INTERVAL)
157 errno = ETIMEDOUT;
9db8d71f 158 net_close (scb);
7c7a201a
MH
159 return -1;
160 }
161 }
c906108c 162
7c7a201a
MH
163 /* Got something. Is it an error? */
164 {
165 int res, err, len;
166 len = sizeof(err);
167 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
168 if (res < 0 || err)
169 {
170 if (err)
171 errno = err;
9db8d71f 172 net_close (scb);
7c7a201a
MH
173 return -1;
174 }
175 }
9db8d71f 176
7c7a201a
MH
177 /* turn off nonblocking */
178 tmp = 0;
179 ioctl (scb->fd, FIONBIO, &tmp);
180
9db8d71f
DJ
181 if (use_udp == 0)
182 {
183 /* Disable Nagle algorithm. Needed in some cases. */
184 tmp = 1;
185 setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
186 (char *)&tmp, sizeof (tmp));
187 }
188
6d318c73 189#ifdef SIGPIPE
7c7a201a
MH
190 /* If we don't do this, then GDB simply exits
191 when the remote side dies. */
192 signal (SIGPIPE, SIG_IGN);
6d318c73 193#endif
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 211 struct serial_ops *ops = XMALLOC (struct serial_ops);
2fdbdd39 212 memset (ops, 0, sizeof (struct serial_ops));
c2c6d25f
JM
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}