1/* Serial interface for raw TCP connections on Un*x like systems 2 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 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. 11 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. 16 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. */ 21 22#include "defs.h" 23#include "serial.h" 24#include "ser-unix.h" 25 26#include <sys/types.h> 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 35#include <sys/time.h> 36#include <netinet/in.h> 37#include <arpa/inet.h> 38#include <netdb.h> 39#include <sys/socket.h> 40#include <netinet/tcp.h> 41 42#include <signal.h> 43#include "gdb_string.h" 44 45static int net_open (struct serial *scb, const char *name); 46static void net_close (struct serial *scb); 47extern int (*ui_loop_hook) (int); 48void _initialize_ser_tcp (void); 49 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 */ 56 57static int 58net_open (struct serial *scb, const char *name) 59{ 60 char *port_str, hostname[100]; 61 int n, port, tmp; 62 int use_udp; 63 struct hostent *hostent; 64 struct sockaddr_in sockaddr; 65 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 75 port_str = strchr (name, ':'); 76 77 if (!port_str) 78 error ("net_open: No colon in host name!"); /* Shouldn't ever happen */ 79 80 tmp = min (port_str - name, (int) sizeof hostname - 1); 81 strncpy (hostname, name, tmp); /* Don't want colon */ 82 hostname[tmp] = '\000'; /* Tie off host name */ 83 port = atoi (port_str + 1); 84 85 /* default hostname is localhost */ 86 if (!hostname[0]) 87 strcpy (hostname, "localhost"); 88 89 hostent = gethostbyname (hostname); 90 if (!hostent) 91 { 92 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname); 93 errno = ENOENT; 94 return -1; 95 } 96 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 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)); 109 110 /* set socket nonblocking */ 111 tmp = 1; 112 ioctl (scb->fd, FIONBIO, &tmp); 113 114 /* Use Non-blocking connect. connect() will return 0 if connected already. */ 115 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); 116 117 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