1/* Serial interface for raw TCP connections on Un*x like systems. 2 3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2005, 2006, 4 2007 Free Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include "defs.h" 22#include "serial.h" 23#include "ser-base.h" 24#include "ser-tcp.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 37#ifdef USE_WIN32API 38#include <winsock2.h> 39#define ETIMEDOUT WSAETIMEDOUT 40#define close(fd) closesocket (fd) 41#define ioctl ioctlsocket 42#else 43#include <netinet/in.h> 44#include <arpa/inet.h> 45#include <netdb.h> 46#include <sys/socket.h> 47#include <netinet/tcp.h> 48#endif 49 50#include <signal.h> 51#include "gdb_string.h" 52 53#ifndef HAVE_SOCKLEN_T 54typedef int socklen_t; 55#endif 56 57void _initialize_ser_tcp (void); 58 59/* seconds to wait for connect */ 60#define TIMEOUT 15 61/* how many times per second to poll deprecated_ui_loop_hook */ 62#define POLL_INTERVAL 2 63 64/* Open a tcp socket */ 65 66int 67net_open (struct serial *scb, const char *name) 68{ 69 char *port_str, hostname[100]; 70 int n, port, tmp; 71 int use_udp; 72 struct hostent *hostent; 73 struct sockaddr_in sockaddr; 74#ifdef USE_WIN32API 75 u_long ioarg; 76#else 77 int ioarg; 78#endif 79 80 use_udp = 0; 81 if (strncmp (name, "udp:", 4) == 0) 82 { 83 use_udp = 1; 84 name = name + 4; 85 } 86 else if (strncmp (name, "tcp:", 4) == 0) 87 name = name + 4; 88 89 port_str = strchr (name, ':'); 90 91 if (!port_str) 92 error (_("net_open: No colon in host name!")); /* Shouldn't ever happen */ 93 94 tmp = min (port_str - name, (int) sizeof hostname - 1); 95 strncpy (hostname, name, tmp); /* Don't want colon */ 96 hostname[tmp] = '\000'; /* Tie off host name */ 97 port = atoi (port_str + 1); 98 99 /* default hostname is localhost */ 100 if (!hostname[0]) 101 strcpy (hostname, "localhost"); 102 103 hostent = gethostbyname (hostname); 104 if (!hostent) 105 { 106 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname); 107 errno = ENOENT; 108 return -1; 109 } 110 111 if (use_udp) 112 scb->fd = socket (PF_INET, SOCK_DGRAM, 0); 113 else 114 scb->fd = socket (PF_INET, SOCK_STREAM, 0); 115 116 if (scb->fd < 0) 117 return -1; 118 119 sockaddr.sin_family = PF_INET; 120 sockaddr.sin_port = htons (port); 121 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, 122 sizeof (struct in_addr)); 123 124 /* set socket nonblocking */ 125 ioarg = 1; 126 ioctl (scb->fd, FIONBIO, &ioarg); 127 128 /* Use Non-blocking connect. connect() will return 0 if connected already. */ 129 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); 130 131 if (n < 0 132#ifdef USE_WIN32API 133 /* Under Windows, calling "connect" with a non-blocking socket 134 results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */ 135 && WSAGetLastError() != WSAEWOULDBLOCK 136#else 137 && errno != EINPROGRESS 138#endif 139 ) 140 { 141#ifdef USE_WIN32API 142 errno = WSAGetLastError(); 143#endif 144 net_close (scb); 145 return -1; 146 } 147 148 if (n) 149 { 150 /* looks like we need to wait for the connect */ 151 struct timeval t; 152 fd_set rset, wset, eset; 153 int polls = 0; 154 FD_ZERO (&rset); 155 156 do 157 { 158 /* While we wait for the connect to complete, 159 poll the UI so it can update or the user can 160 interrupt. */ 161 if (deprecated_ui_loop_hook) 162 { 163 if (deprecated_ui_loop_hook (0)) 164 { 165 errno = EINTR; 166 net_close (scb); 167 return -1; 168 } 169 } 170 171 FD_SET (scb->fd, &rset); 172 wset = rset; 173 eset = rset; 174 t.tv_sec = 0; 175 t.tv_usec = 1000000 / POLL_INTERVAL; 176 177 /* POSIX systems return connection success or failure by signalling 178 wset. Windows systems return success in wset and failure in 179 eset. 180 181 We must call select here, rather than gdb_select, because 182 the serial structure has not yet been initialized - the 183 MinGW select wrapper will not know that this FD refers 184 to a socket. */ 185 n = select (scb->fd + 1, &rset, &wset, &eset, &t); 186 polls++; 187 } 188 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL); 189 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL) 190 { 191 if (polls > TIMEOUT * POLL_INTERVAL) 192 errno = ETIMEDOUT; 193 net_close (scb); 194 return -1; 195 } 196 } 197 198 /* Got something. Is it an error? */ 199 { 200 int res, err; 201 socklen_t len; 202 len = sizeof (err); 203 /* On Windows, the fourth parameter to getsockopt is a "char *"; 204 on UNIX systems it is generally "void *". The cast to "void *" 205 is OK everywhere, since in C "void *" can be implicitly 206 converted to any pointer type. */ 207 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len); 208 if (res < 0 || err) 209 { 210 if (err) 211 errno = err; 212 net_close (scb); 213 return -1; 214 } 215 } 216 217 /* turn off nonblocking */ 218 ioarg = 0; 219 ioctl (scb->fd, FIONBIO, &ioarg); 220 221 if (use_udp == 0) 222 { 223 /* Disable Nagle algorithm. Needed in some cases. */ 224 tmp = 1; 225 setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, 226 (char *)&tmp, sizeof (tmp)); 227 } 228 229#ifdef SIGPIPE 230 /* If we don't do this, then GDB simply exits 231 when the remote side dies. */ 232 signal (SIGPIPE, SIG_IGN); 233#endif 234 235 return 0; 236} 237 238void 239net_close (struct serial *scb) 240{ 241 if (scb->fd < 0) 242 return; 243 244 close (scb->fd); 245 scb->fd = -1; 246} 247 248int 249net_read_prim (struct serial *scb, size_t count) 250{ 251 return recv (scb->fd, scb->buf, count, 0); 252} 253 254int 255net_write_prim (struct serial *scb, const void *buf, size_t count) 256{ 257 return send (scb->fd, buf, count, 0); 258} 259 260void 261_initialize_ser_tcp (void) 262{ 263#ifdef USE_WIN32API 264 /* Do nothing; the TCP serial operations will be initialized in 265 ser-mingw.c. */ 266 return; 267#else 268 struct serial_ops *ops; 269 ops = XMALLOC (struct serial_ops); 270 memset (ops, 0, sizeof (struct serial_ops)); 271 ops->name = "tcp"; 272 ops->next = 0; 273 ops->open = net_open; 274 ops->close = net_close; 275 ops->readchar = ser_base_readchar; 276 ops->write = ser_base_write; 277 ops->flush_output = ser_base_flush_output; 278 ops->flush_input = ser_base_flush_input; 279 ops->send_break = ser_base_send_break; 280 ops->go_raw = ser_base_raw; 281 ops->get_tty_state = ser_base_get_tty_state; 282 ops->set_tty_state = ser_base_set_tty_state; 283 ops->print_tty_state = ser_base_print_tty_state; 284 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 285 ops->setbaudrate = ser_base_setbaudrate; 286 ops->setstopbits = ser_base_setstopbits; 287 ops->drain_output = ser_base_drain_output; 288 ops->async = ser_base_async; 289 ops->read_prim = net_read_prim; 290 ops->write_prim = net_write_prim; 291 serial_add_interface (ops); 292#endif /* USE_WIN32API */ 293} 294