@@ -168,6 +168,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
s->chr_read(s->handler_opaque, buf, len);
}
+void qemu_chr_recvmsg(CharDriverState *s, struct msghdr *msg, int flags)
+{
+ s->chr_read(s->handler_opaque, msg, flags);
+}
+
void qemu_chr_accept_input(CharDriverState *s)
{
if (s->chr_accept_input)
@@ -1652,6 +1657,7 @@ static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
WinCharState *s;
chr = qemu_mallocz(sizeof(CharDriverState));
+
s = qemu_mallocz(sizeof(WinCharState));
chr->opaque = s;
chr->chr_write = win_chr_write;
@@ -1937,6 +1943,72 @@ static void tcp_chr_read(void *opaque)
}
}
+/* this is a new function that will replace tcp_chr_read (which calls recv)
+ * with this one that calls recvmsg instead when we want to use recvmsg */
+static void tcp_chr_recvmsg(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
+ struct msghdr msg;
+ uint8_t buf[1024];
+ int len, size;
+ char control[CMSG_SPACE(RECVMSG_MAX)];
+ struct iovec iov[8];
+
+ printf("inside tcp_chr_recvmsg\n");
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+ msg.msg_flags = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 1024;
+
+ if (!s->connected || s->max_size <= 0)
+ return;
+ len = sizeof(control);
+ if (len > s->max_size)
+ len = s->max_size;
+// size = recv(s->fd, buf, len, 0);
+ printf("calling recvmsg\n");
+ size = recvmsg(s->fd, &msg, 0);
+ if (size == 0) {
+ /* connection closed */
+ s->connected = 0;
+ if (s->listen_fd >= 0) {
+ qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
+ }
+ qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+ closesocket(s->fd);
+ s->fd = -1;
+ } else if (size > 0) {
+ if (s->do_telnetopt)
+ tcp_chr_process_IAC_bytes(chr, s, buf, &size);
+ if (size > 0)
+ qemu_chr_recvmsg(chr, &msg, 0);
+ }
+
+
+}
+
+void tcp_switch_to_recvmsg_handlers(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
+
+ qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
+ tcp_chr_recvmsg, NULL, chr);
+}
+
+CharDriverState *qemu_chr_open_eventfd(int eventfd){
+
+ return qemu_chr_open_fd(eventfd, eventfd);
+
+}
+
static void tcp_chr_connect(void *opaque)
{
CharDriverState *chr = opaque;
@@ -44,6 +44,8 @@ typedef struct {
#define CHR_TIOCM_DTR 0x002
#define CHR_TIOCM_RTS 0x004
+#define RECVMSG_MAX 1024
+
typedef void IOEventHandler(void *opaque, int event);
struct CharDriverState {
@@ -84,6 +86,12 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
void qemu_chr_accept_input(CharDriverState *s);
void qemu_chr_info(Monitor *mon);
+/* function to change tcp_chr_read to tcp_chr_recvmsg */
+void tcp_switch_to_recvmsg_handlers(void *opaque);
+
+/* add an eventfd to the qemu devices that are polled */
+CharDriverState *qemu_chr_open_eventfd(int eventfd);
+
extern int term_escape_char;
/* async I/O support */