1/* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. 2 Copyright (C) 1994 Advanced RISC Machines Ltd. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 17 18/**************************************************************************/ 19/* Functions to read and write characters or groups of characters */ 20/* down sockets or pipes. Those that return a value return -1 on failure */ 21/* and 0 on success. */ 22/**************************************************************************/ 23 24#include <sys/time.h> 25#include <sys/types.h> 26#include <sys/socket.h> 27#include <netinet/in.h> 28 29#include "armdefs.h" 30 31/* The socket to the debugger */ 32int debugsock; 33 34/* The maximum number of file descriptors */ 35extern int nfds; 36 37/* The socket handle */ 38extern int sockethandle; 39 40/* Read and Write routines down a pipe or socket */ 41 42/****************************************************************/ 43/* Read an individual character. */ 44/* All other read functions rely on this one. */ 45/* It waits 15 seconds until there is a character available: if */ 46/* no character is available, then it timeouts and returns -1. */ 47/****************************************************************/ 48int 49MYread_char (int sock, unsigned char *c) 50{ 51 int i; 52 fd_set readfds; 53 struct timeval timeout = { 15, 0 }; 54 struct sockaddr_in isa; 55 56retry: 57 58 FD_ZERO (&readfds); 59 FD_SET (sock, &readfds); 60 61 i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout); 62 63 if (i < 0) 64 { 65 perror ("select"); 66 exit (1); 67 } 68 69 if (!i) 70 { 71 fprintf (stderr, "read: Timeout\n"); 72 return -1; 73 } 74 75 if ((i = read (sock, c, 1)) < 1) 76 { 77 if (!i && sock == debugsock) 78 { 79 fprintf (stderr, "Connection with debugger severed.\n"); 80 /* This shouldn't be necessary for a detached armulator, but 81 the armulator cannot be cold started a second time, so 82 this is probably preferable to locking up. */ 83 return -1; 84 fprintf (stderr, "Waiting for connection from debugger..."); 85 debugsock = accept (sockethandle, &isa, &i); 86 if (debugsock < 0) 87 { /* Now we are in serious trouble... */ 88 perror ("accept"); 89 return -1; 90 } 91 fprintf (stderr, " done.\nConnection Established.\n"); 92 sock = debugsock; 93 goto retry; 94 } 95 perror ("read"); 96 return -1; 97 } 98 99#ifdef DEBUG 100 if (sock == debugsock) 101 fprintf (stderr, "<%02x ", *c); 102#endif 103 104 return 0; 105} 106 107/****************************************************************/ 108/* Read an individual character. */ 109/* It waits until there is a character available. Returns -1 if */ 110/* an error occurs. */ 111/****************************************************************/ 112int 113MYread_charwait (int sock, unsigned char *c) 114{ 115 int i; 116 fd_set readfds; 117 struct sockaddr_in isa; 118 119retry: 120 121 FD_ZERO (&readfds); 122 FD_SET (sock, &readfds); 123 124 i = select (nfds, &readfds, 125 (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); 126 127 if (i < 0) 128 { 129 perror ("select"); 130 exit (-1); 131 } 132 133 if ((i = read (sock, c, 1)) < 1) 134 { 135 if (!i && sock == debugsock) 136 { 137 fprintf (stderr, "Connection with debugger severed.\n"); 138 return -1; 139 fprintf (stderr, "Waiting for connection from debugger..."); 140 debugsock = accept (sockethandle, &isa, &i); 141 if (debugsock < 0) 142 { /* Now we are in serious trouble... */ 143 perror ("accept"); 144 return -1; 145 } 146 fprintf (stderr, " done.\nConnection Established.\n"); 147 sock = debugsock; 148 goto retry; 149 } 150 perror ("read"); 151 return -1; 152 } 153 154#ifdef DEBUG 155 if (sock == debugsock) 156 fprintf (stderr, "<%02x ", *c); 157#endif 158 159 return 0; 160} 161 162void 163MYwrite_char (int sock, unsigned char c) 164{ 165 166 if (write (sock, &c, 1) < 1) 167 perror ("write"); 168#ifdef DEBUG 169 if (sock == debugsock) 170 fprintf (stderr, ">%02x ", c); 171#endif 172} 173 174int 175MYread_word (int sock, ARMword * here) 176{ 177 unsigned char a, b, c, d; 178 179 if (MYread_char (sock, &a) < 0) 180 return -1; 181 if (MYread_char (sock, &b) < 0) 182 return -1; 183 if (MYread_char (sock, &c) < 0) 184 return -1; 185 if (MYread_char (sock, &d) < 0) 186 return -1; 187 *here = a | b << 8 | c << 16 | d << 24; 188 return 0; 189} 190 191void 192MYwrite_word (int sock, ARMword i) 193{ 194 MYwrite_char (sock, i & 0xff); 195 MYwrite_char (sock, (i & 0xff00) >> 8); 196 MYwrite_char (sock, (i & 0xff0000) >> 16); 197 MYwrite_char (sock, (i & 0xff000000) >> 24); 198} 199 200void 201MYwrite_string (int sock, char *s) 202{ 203 int i; 204 for (i = 0; MYwrite_char (sock, s[i]), s[i]; i++); 205} 206 207int 208MYread_FPword (int sock, char *putinhere) 209{ 210 int i; 211 for (i = 0; i < 16; i++) 212 if (MYread_char (sock, &putinhere[i]) < 0) 213 return -1; 214 return 0; 215} 216 217void 218MYwrite_FPword (int sock, char *fromhere) 219{ 220 int i; 221 for (i = 0; i < 16; i++) 222 MYwrite_char (sock, fromhere[i]); 223} 224 225/* Takes n bytes from source and those n bytes */ 226/* down to dest */ 227int 228passon (int source, int dest, int n) 229{ 230 char *p; 231 int i; 232 233 p = (char *) malloc (n); 234 if (!p) 235 { 236 perror ("Out of memory\n"); 237 exit (1); 238 } 239 if (n) 240 { 241 for (i = 0; i < n; i++) 242 if (MYread_char (source, &p[i]) < 0) 243 return -1; 244 245#ifdef DEBUG 246 if (dest == debugsock) 247 for (i = 0; i < n; i++) 248 fprintf (stderr, ")%02x ", (unsigned char) p[i]); 249#endif 250 251 write (dest, p, n); 252 } 253 free (p); 254 return 0; 255} 256