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