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