From bff2c04c5b7fd38f6ecc1fcd460ded36a30d3072 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 10 Jul 2005 16:51:09 +0000 Subject: [PATCH] - com->socket redirection support added (initial SF patch #1107945 by Andrew Backer) --- bochs/config.cc | 5 ++- bochs/iodev/serial.cc | 99 +++++++++++++++++++++++++++++++++++++++++-- bochs/iodev/serial.h | 10 ++++- 3 files changed, 106 insertions(+), 8 deletions(-) diff --git a/bochs/config.cc b/bochs/config.cc index 6ced5a37a..01d5bcf32 100755 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: config.cc,v 1.36 2005-06-08 18:25:49 vruppert Exp $ +// $Id: config.cc,v 1.37 2005-07-10 16:51:08 vruppert Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -866,6 +866,7 @@ void bx_init_options () "term", "raw", "mouse", + "socket", NULL }; @@ -880,7 +881,7 @@ void bx_init_options () strdup(descr), (i==0)?1 : 0); // only enable the first by default sprintf (name, "I/O mode of the serial device for COM%d", i+1); - sprintf (descr, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse'"); + sprintf (descr, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket'"); bx_options.com[i].Omode = new bx_param_enum_c ( BXP_COMx_MODE(i+1), strdup(name), diff --git a/bochs/iodev/serial.cc b/bochs/iodev/serial.cc index 080015186..e6c26bd50 100644 --- a/bochs/iodev/serial.cc +++ b/bochs/iodev/serial.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: serial.cc,v 1.64 2005-01-19 18:21:37 sshwarts Exp $ +// $Id: serial.cc,v 1.65 2005-07-10 16:51:08 vruppert Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2004 MandrakeSoft S.A. @@ -38,6 +38,10 @@ #define BX_PLUGGABLE #include "iodev.h" +#ifndef WIN32 +#include +#include +#endif #if USE_RAW_SERIAL #include "serial_raw.h" @@ -83,7 +87,7 @@ bx_serial_c::~bx_serial_c(void) fclose(BX_SER_THIS s[i].output); break; case BX_SER_MODE_TERM: -#if defined(SERIAL_ENABLE) +#if defined(SERIAL_ENABLE) && !defined(WIN32) if (s[i].tty_id >= 0) { tcsetattr(s[i].tty_id, TCSAFLUSH, &s[i].term_orig); } @@ -94,6 +98,9 @@ bx_serial_c::~bx_serial_c(void) delete [] BX_SER_THIS s[i].raw; #endif break; + case BX_SER_MODE_SOCKET: + if (BX_SER_THIS s[i].socket_id >= 0) ::close(BX_SER_THIS s[i].socket_id); + break; } } } @@ -228,11 +235,11 @@ bx_serial_c::init(void) BX_SER_THIS s[i].io_mode = BX_SER_MODE_FILE; } } else if (!strcmp(mode, "term")) { -#if defined(SERIAL_ENABLE) +#if defined(SERIAL_ENABLE) && !defined(WIN32) if (strlen(bx_options.com[i].Odev->getptr ()) > 0) { BX_SER_THIS s[i].tty_id = open(bx_options.com[i].Odev->getptr (), O_RDWR|O_NONBLOCK,600); if (BX_SER_THIS s[i].tty_id < 0) { - BX_PANIC(("open of com%d (%s) failed\n", i+1, bx_options.com[i].Odev->getptr ())); + BX_PANIC(("open of com%d (%s) failed", i+1, bx_options.com[i].Odev->getptr ())); } else { BX_SER_THIS s[i].io_mode = BX_SER_MODE_TERM; BX_DEBUG(("com%d tty_id: %d", i+1, BX_SER_THIS s[i].tty_id)); @@ -273,6 +280,59 @@ bx_serial_c::init(void) } else if (!strcmp(mode, "mouse")) { BX_SER_THIS s[i].io_mode = BX_SER_MODE_MOUSE; BX_SER_THIS mouse_port = i; + } else if (!strcmp(mode, "socket")) { + BX_SER_THIS s[i].io_mode = BX_SER_MODE_SOCKET; + struct sockaddr_in sin; + struct hostent *hp; + char host[BX_PATHNAME_LEN]; + int port; + int socket; + +#if defined(WIN32) + static bool winsock_init = false; + if (!winsock_init) { + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD (2, 0); + err = WSAStartup (wVersionRequested, &wsaData); + if (err != 0) + BX_PANIC (("WSAStartup failed")); + winsock_init = true; + } +#endif + + char *substr = strtok(bx_options.com[i].Odev->getptr(), ":"); + strcpy(host, substr); + substr = strtok(NULL, ":"); + if (!substr) { + BX_PANIC(("com%d: inet address is wrong (%s)", i+1, + bx_options.com[i].Odev->getptr ())); + } + port = atoi (substr); + + hp = gethostbyname (host); + if (!hp) { + BX_PANIC(("com%d: gethostbyname failed (%s)", i+1, host)); + } + + memset ((char*) &sin, 0, sizeof (sin)); + memcpy ((char*) &(sin.sin_addr), hp->h_addr, hp->h_length); + sin.sin_family = hp->h_addrtype; + sin.sin_port = htons (port); + + socket = ::socket (AF_INET, SOCK_STREAM, 0); + if (socket < 0) { + BX_PANIC(("com%d: socket() failed",i+1)); + } + + if (::connect (socket, (sockaddr *) &sin, sizeof (sin)) < 0) { + socket = -1; + BX_INFO(("com%d: connect() failed (host:%s, port:%d)",i+1, host, port)); + } else { + BX_INFO(("com%d - inet - socket_id: %d, ip:%s, port:%d", i+1, socket, host, port)); + } + BX_SER_THIS s[i].socket_id = socket; } else if (strcmp(mode, "null")) { BX_PANIC(("unknown serial i/o mode")); } @@ -1049,6 +1109,17 @@ bx_serial_c::tx_timer(void) case BX_SER_MODE_MOUSE: BX_INFO(("com%d: write to mouse ignored: 0x%02x", port+1, BX_SER_THIS s[port].tsrbuffer)); break; + case BX_SER_MODE_SOCKET: + if (BX_SER_THIS s[port].socket_id >= 0) { +#ifdef WIN32 + BX_INFO(("attempting to write win32 : %c", BX_SER_THIS s[port].tsrbuffer)); + ::send(BX_SER_THIS s[port].socket_id, + (const char*) & BX_SER_THIS s[port].tsrbuffer, 1, 0); +#else + ::write(BX_SER_THIS s[port].socket_id, + (bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1); +#endif + } } } @@ -1127,6 +1198,26 @@ bx_serial_c::rx_timer(void) if ((BX_SER_THIS s[port].line_status.rxdata_ready == 0) || (BX_SER_THIS s[port].fifo_cntl.enable)) { switch (BX_SER_THIS s[port].io_mode) { + case BX_SER_MODE_SOCKET: +#if defined(SERIAL_ENABLE) + if (BX_SER_THIS s[port].line_status.rxdata_ready == 0) { + tval.tv_sec = 0; + tval.tv_usec = 0; + FD_ZERO(&fds); + int socketid = BX_SER_THIS s[port].socket_id; + if (socketid >= 0) FD_SET(socketid, &fds); + if ((socketid >= 0) && (select(socketid+1, &fds, NULL, NULL, &tval) == 1)) { +#ifdef WIN32 + (void) ::recv(socketid, (char*) &chbuf, 1, 0); +#else + (void) read(socketid, &chbuf, 1); +#endif + BX_INFO((" -- COM %d : read byte [%d]", port+1, chbuf)); + data_ready = 1; + } + } +#endif + break; case BX_SER_MODE_RAW: #if USE_RAW_SERIAL int data; diff --git a/bochs/iodev/serial.h b/bochs/iodev/serial.h index f01bf48b5..98f84192c 100644 --- a/bochs/iodev/serial.h +++ b/bochs/iodev/serial.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: serial.h,v 1.25 2004-12-05 20:23:39 vruppert Exp $ +// $Id: serial.h,v 1.26 2005-07-10 16:51:09 vruppert Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2004 MandrakeSoft S.A. @@ -36,6 +36,10 @@ # define BX_SER_THIS this-> #endif +#if defined(WIN32) +#define SERIAL_ENABLE +#endif + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) || defined(__APPLE__) #define SERIAL_ENABLE extern "C" { @@ -67,6 +71,7 @@ extern "C" { #define BX_SER_MODE_TERM 2 #define BX_SER_MODE_RAW 3 #define BX_SER_MODE_MOUSE 4 +#define BX_SER_MODE_SOCKET 5 enum { BX_SER_INT_IER, @@ -109,12 +114,13 @@ typedef struct { int io_mode; int tty_id; + int socket_id; FILE *output; #if USE_RAW_SERIAL serial_raw* raw; #endif -#if defined(SERIAL_ENABLE) +#if defined(SERIAL_ENABLE) && !defined(WIN32) struct termios term_orig, term_new; #endif