1270310Sse/* Serial interface for raw TCP connections on Un*x like systems 2270310Sse Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001 343334Syokota Free Software Foundation, Inc. 443334Syokota 543334Syokota This file is part of GDB. 643334Syokota 743334Syokota This program is free software; you can redistribute it and/or modify 843334Syokota it under the terms of the GNU General Public License as published by 943334Syokota the Free Software Foundation; either version 2 of the License, or 1043334Syokota (at your option) any later version. 1143334Syokota 12270310Sse This program is distributed in the hope that it will be useful, 1343334Syokota but WITHOUT ANY WARRANTY; without even the implied warranty of 14270310Sse MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15270310Sse GNU General Public License for more details. 16270310Sse 1743334Syokota You should have received a copy of the GNU General Public License 18270310Sse along with this program; if not, write to the Free Software 1943334Syokota Foundation, Inc., 59 Temple Place - Suite 330, 20270310Sse Boston, MA 02111-1307, USA. */ 21270310Sse 22270310Sse#include "defs.h" 2343334Syokota#include "serial.h" 2443334Syokota#include "ser-unix.h" 2543334Syokota 2643334Syokota#include <sys/types.h> 2743334Syokota 2843334Syokota#ifdef HAVE_SYS_FILIO_H 2943334Syokota#include <sys/filio.h> /* For FIONBIO. */ 3043334Syokota#endif 3143334Syokota#ifdef HAVE_SYS_IOCTL_H 3243334Syokota#include <sys/ioctl.h> /* For FIONBIO. */ 3343334Syokota#endif 3443334Syokota 35270310Sse#include <sys/time.h> 36270310Sse#include <netinet/in.h> 3743334Syokota#include <arpa/inet.h> 3843334Syokota#include <netdb.h> 3943334Syokota#include <sys/socket.h> 4043334Syokota#include <netinet/tcp.h> 4143334Syokota 4243334Syokota#include <signal.h> 4343334Syokota#include "gdb_string.h" 4443334Syokota 4543334Syokotastatic int net_open (struct serial *scb, const char *name); 46270310Ssestatic void net_close (struct serial *scb); 47270310Sseextern int (*ui_loop_hook) (int); 48270310Ssevoid _initialize_ser_tcp (void); 49270310Sse 50270310Sse/* seconds to wait for connect */ 5143334Syokota#define TIMEOUT 15 52270310Sse/* how many times per second to poll ui_loop_hook */ 5343334Syokota#define POLL_INTERVAL 2 5443334Syokota 5543334Syokota/* Open a tcp socket */ 5643334Syokota 5743334Syokotastatic int 5843334Syokotanet_open (struct serial *scb, const char *name) 59270310Sse{ 60166500Sphilip char *port_str, hostname[100]; 61166500Sphilip int n, port, tmp; 6243334Syokota int use_udp; 6343334Syokota struct hostent *hostent; 6443334Syokota struct sockaddr_in sockaddr; 6543334Syokota 6643334Syokota use_udp = 0; 6743334Syokota if (strncmp (name, "udp:", 4) == 0) 6843334Syokota { 6943334Syokota use_udp = 1; 7043334Syokota name = name + 4; 7143334Syokota } 7243334Syokota else if (strncmp (name, "tcp:", 4) == 0) 7343334Syokota name = name + 4; 7443334Syokota 7543334Syokota port_str = strchr (name, ':'); 7643334Syokota 7743334Syokota if (!port_str) 7843334Syokota error ("net_open: No colon in host name!"); /* Shouldn't ever happen */ 7943334Syokota 8043334Syokota tmp = min (port_str - name, (int) sizeof hostname - 1); 8143334Syokota strncpy (hostname, name, tmp); /* Don't want colon */ 8243334Syokota hostname[tmp] = '\000'; /* Tie off host name */ 8343334Syokota port = atoi (port_str + 1); 8443334Syokota 8543334Syokota /* default hostname is localhost */ 8643334Syokota if (!hostname[0]) 8743334Syokota strcpy (hostname, "localhost"); 8843334Syokota 8943334Syokota hostent = gethostbyname (hostname); 9043334Syokota if (!hostent) 9143334Syokota { 9243334Syokota fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname); 9343334Syokota errno = ENOENT; 9443334Syokota return -1; 9543334Syokota } 9643334Syokota 9743334Syokota if (use_udp) 9843334Syokota scb->fd = socket (PF_INET, SOCK_DGRAM, 0); 9943334Syokota else 10043334Syokota scb->fd = socket (PF_INET, SOCK_STREAM, 0); 10174119Sache 10243334Syokota if (scb->fd < 0) 10343334Syokota return -1; 10443334Syokota 10543334Syokota sockaddr.sin_family = PF_INET; 10643334Syokota sockaddr.sin_port = htons (port); 10743334Syokota memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, 10843334Syokota sizeof (struct in_addr)); 10943334Syokota 11043334Syokota /* set socket nonblocking */ 11174119Sache tmp = 1; 112270310Sse ioctl (scb->fd, FIONBIO, &tmp); 11343334Syokota 11443334Syokota /* Use Non-blocking connect. connect() will return 0 if connected already. */ 11543334Syokota n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); 11643334Syokota 11743334Syokota if (n < 0 && errno != EINPROGRESS) 118 { 119 net_close (scb); 120 return -1; 121 } 122 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; 141 net_close (scb); 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; 159 net_close (scb); 160 return -1; 161 } 162 } 163 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; 173 net_close (scb); 174 return -1; 175 } 176 } 177 178 /* turn off nonblocking */ 179 tmp = 0; 180 ioctl (scb->fd, FIONBIO, &tmp); 181 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 190 /* If we don't do this, then GDB simply exits 191 when the remote side dies. */ 192 signal (SIGPIPE, SIG_IGN); 193 194 return 0; 195} 196 197static void 198net_close (struct serial *scb) 199{ 200 if (scb->fd < 0) 201 return; 202 203 close (scb->fd); 204 scb->fd = -1; 205} 206 207void 208_initialize_ser_tcp (void) 209{ 210 struct serial_ops *ops = XMALLOC (struct serial_ops); 211 memset (ops, 0, sizeof (struct serial_ops)); 212 ops->name = "tcp"; 213 ops->next = 0; 214 ops->open = net_open; 215 ops->close = net_close; 216 ops->readchar = ser_unix_readchar; 217 ops->write = ser_unix_write; 218 ops->flush_output = ser_unix_nop_flush_output; 219 ops->flush_input = ser_unix_flush_input; 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); 231} 232