2001-12-07 Martin M. Hunt <hunt@redhat.com>
[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>
c906108c 41
042be3a9 42#include <signal.h>
c906108c
SS
43#include "gdb_string.h"
44
819cc324
AC
45static int tcp_open (struct serial *scb, const char *name);
46static void tcp_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
819cc324 58tcp_open (struct serial *scb, const char *name)
c906108c 59{
7c7a201a
MH
60 char *port_str, hostname[100];
61 int n, port, tmp;
c906108c
SS
62 struct hostent *hostent;
63 struct sockaddr_in sockaddr;
c906108c
SS
64
65 port_str = strchr (name, ':');
66
67 if (!port_str)
7c7a201a 68 error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
c906108c
SS
69
70 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 71 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
72 hostname[tmp] = '\000'; /* Tie off host name */
73 port = atoi (port_str + 1);
74
7c7a201a 75 /* default hostname is localhost */
ad4571f3
CV
76 if (!hostname[0])
77 strcpy (hostname, "localhost");
78
c906108c 79 hostent = gethostbyname (hostname);
c906108c
SS
80 if (!hostent)
81 {
82 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
83 errno = ENOENT;
84 return -1;
85 }
86
7c7a201a
MH
87 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
88 if (scb->fd < 0)
89 return -1;
90
91 sockaddr.sin_family = PF_INET;
92 sockaddr.sin_port = htons (port);
93 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
94 sizeof (struct in_addr));
c906108c 95
7c7a201a
MH
96 /* set socket nonblocking */
97 tmp = 1;
98 ioctl (scb->fd, FIONBIO, &tmp);
c906108c 99
7c7a201a
MH
100 /* Use Non-blocking connect. connect() will return 0 if connected already. */
101 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
c906108c 102
7c7a201a
MH
103 if (n < 0 && errno != EINPROGRESS)
104 {
105 tcp_close (scb);
106 return -1;
c906108c
SS
107 }
108
7c7a201a
MH
109 if (n)
110 {
111 /* looks like we need to wait for the connect */
112 struct timeval t;
113 fd_set rset, wset;
114 int polls = 0;
115 FD_ZERO (&rset);
116
117 do
118 {
119 /* While we wait for the connect to complete
120 poll the UI so it can update or the user can
121 interrupt. */
122 if (ui_loop_hook)
123 {
124 if (ui_loop_hook (0))
125 {
126 errno = EINTR;
127 tcp_close (scb);
128 return -1;
129 }
130 }
131
132 FD_SET (scb->fd, &rset);
133 wset = rset;
134 t.tv_sec = 0;
135 t.tv_usec = 1000000 / POLL_INTERVAL;
136
137 n = select (scb->fd + 1, &rset, &wset, NULL, &t);
138 polls++;
139 }
140 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
141 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
142 {
143 if (polls > TIMEOUT * POLL_INTERVAL)
144 errno = ETIMEDOUT;
145 tcp_close (scb);
146 return -1;
147 }
148 }
c906108c 149
7c7a201a
MH
150 /* Got something. Is it an error? */
151 {
152 int res, err, len;
153 len = sizeof(err);
154 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
155 if (res < 0 || err)
156 {
157 if (err)
158 errno = err;
159 tcp_close (scb);
160 return -1;
161 }
162 }
163
164 /* turn off nonblocking */
165 tmp = 0;
166 ioctl (scb->fd, FIONBIO, &tmp);
167
168 /* If we don't do this, then GDB simply exits
169 when the remote side dies. */
170 signal (SIGPIPE, SIG_IGN);
c906108c
SS
171
172 return 0;
173}
174
c906108c 175static void
819cc324 176tcp_close (struct serial *scb)
c906108c
SS
177{
178 if (scb->fd < 0)
179 return;
180
c5aa993b 181 close (scb->fd);
c906108c
SS
182 scb->fd = -1;
183}
184
c906108c 185void
c2c6d25f 186_initialize_ser_tcp (void)
c906108c 187{
c2c6d25f
JM
188 struct serial_ops *ops = XMALLOC (struct serial_ops);
189 memset (ops, sizeof (struct serial_ops), 0);
190 ops->name = "tcp";
191 ops->next = 0;
192 ops->open = tcp_open;
193 ops->close = tcp_close;
194 ops->readchar = ser_unix_readchar;
195 ops->write = ser_unix_write;
196 ops->flush_output = ser_unix_nop_flush_output;
2acceee2 197 ops->flush_input = ser_unix_flush_input;
c2c6d25f
JM
198 ops->send_break = ser_unix_nop_send_break;
199 ops->go_raw = ser_unix_nop_raw;
200 ops->get_tty_state = ser_unix_nop_get_tty_state;
201 ops->set_tty_state = ser_unix_nop_set_tty_state;
202 ops->print_tty_state = ser_unix_nop_print_tty_state;
203 ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
204 ops->setbaudrate = ser_unix_nop_setbaudrate;
205 ops->setstopbits = ser_unix_nop_setstopbits;
206 ops->drain_output = ser_unix_nop_drain_output;
207 ops->async = ser_unix_async;
208 serial_add_interface (ops);
c906108c 209}
This page took 0.162325 seconds and 4 git commands to generate.