Index: ioemu/vl.c
===================================================================
--- ioemu.orig/vl.c	2007-05-03 10:24:03.000000000 +0100
+++ ioemu/vl.c	2007-05-03 10:24:04.000000000 +0100
@@ -1537,26 +1537,108 @@
     return chr;
 }
 
+/*
+ * Create a store entry for a device (e.g., monitor, serial/parallel lines).
+ * The entry is <domain-path><storeString>/tty and the value is the name
+ * of the pty associated with the device.
+ */
+static int store_dev_info(char *devName, int domid,
+                          CharDriverState *cState, char *storeString)
+{
+    int xc_handle;
+    struct xs_handle *xs;
+    char *path;
+    char *newpath;
+    FDCharDriver *s;
+    char *pts;
+
+    /* Check for valid arguments (at least, prevent segfaults). */
+    if ((devName == NULL) || (cState == NULL) || (storeString == NULL)) {
+        fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /*
+     * Only continue if we're talking to a pty
+     * Actually, the following code works for any CharDriverState using
+     * FDCharDriver, but we really only care about pty's here
+     */
+    if (strcmp(devName, "pty"))
+        return 0;
+
+    s = cState->opaque;
+    if (s == NULL) {
+        fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n",
+                __FUNCTION__, storeString, devName);
+        return EBADF;
+    }
+
+    pts = ptsname(s->fd_in);
+    if (pts == NULL) {
+        fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', "
+                "error %d (%s)\n",
+                __FUNCTION__, storeString, devName, errno, strerror(errno));
+        return errno;
+    }
+
+    /* We now have everything we need to set the xenstore entry. */
+    xs = xs_daemon_open();
+    if (xs == NULL) {
+        fprintf(logfile, "Could not contact XenStore\n");
+        return -1;
+    }
+
+    xc_handle = xc_interface_open();
+    if (xc_handle == -1) {
+        fprintf(logfile, "xc_interface_open() error\n");
+        return -1;
+    }
+
+    path = xs_get_domain_path(xs, domid);
+    if (path == NULL) {
+        fprintf(logfile, "xs_get_domain_path() error\n");
+        return -1;
+    }
+    newpath = realloc(path, (strlen(path) + strlen(storeString) +
+                             strlen("/tty") + 1));
+    if (newpath == NULL) {
+        free(path); /* realloc errors leave old block */
+        fprintf(logfile, "realloc error\n");
+        return -1;
+    }
+    path = newpath;
+
+    strcat(path, storeString);
+    strcat(path, "/tty");
+    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
+        fprintf(logfile, "xs_write for '%s' fail", storeString);
+        return -1;
+    }
+
+    free(path);
+    xs_daemon_close(xs);
+    close(xc_handle);
+
+    return 0;
+}
+
 #if defined(__linux__)
 CharDriverState *qemu_chr_open_pty(void)
 {
     struct termios tty;
-    char slave_name[1024];
     int master_fd, slave_fd;
     
     /* Not satisfying */
-    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
+    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
         return NULL;
     }
     
-    /* Disabling local echo and line-buffered output */
-    tcgetattr (master_fd, &tty);
-    tty.c_lflag &= ~(ECHO|ICANON|ISIG);
-    tty.c_cc[VMIN] = 1;
-    tty.c_cc[VTIME] = 0;
-    tcsetattr (master_fd, TCSAFLUSH, &tty);
+    /* Set raw attributes on the pty. */
+    cfmakeraw(&tty);
+    tcsetattr(slave_fd, TCSAFLUSH, &tty);
+    
+    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
 
-    fprintf(stderr, "char device redirected to %s\n", slave_name);
     return qemu_chr_open_fd(master_fd, master_fd);
 }
 
@@ -5881,7 +5963,9 @@
                 break;
             case QEMU_OPTION_nographic:
                 pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
-                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
+                if(!strcmp(serial_devices[0], "vc"))
+                    pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
+                            "stdio");
                 nographic = 1;
                 break;
             case QEMU_OPTION_kernel:
@@ -6348,16 +6432,23 @@
         fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
         exit(1);
     }
+    store_dev_info(monitor_device, domid, monitor_hd, "/monitor");
     monitor_init(monitor_hd, !nographic);
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_devices[i][0] != '\0') {
+            char buf[16];
             serial_hds[i] = qemu_chr_open(serial_devices[i]);
             if (!serial_hds[i]) {
                 fprintf(stderr, "qemu: could not open serial device '%s'\n", 
                         serial_devices[i]);
                 exit(1);
             }
+            snprintf(buf, sizeof(buf), "/serial/%d", i);
+            store_dev_info(serial_devices[i], domid, serial_hds[i], buf);
+            if (i == 0) /* serial 0 is also called the console */
+                store_dev_info(serial_devices[i], domid,
+                               serial_hds[i], "/console");
             if (!strcmp(serial_devices[i], "vc"))
                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
         }
@@ -6365,12 +6456,15 @@
 
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         if (parallel_devices[i][0] != '\0') {
+            char buf[16];
             parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
             if (!parallel_hds[i]) {
                 fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
                         parallel_devices[i]);
                 exit(1);
             }
+            snprintf(buf, sizeof(buf), "/parallel/%d", i);
+            store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf);
             if (!strcmp(parallel_devices[i], "vc"))
                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
         }
