changeset: 10286:7887529f51d9a223dee02d5ef3358123bed89958
tag: tip
user: jimix@xxxxxxxxxxxxxxxxxxxxx
date: Tue May 16 15:59:32 2006 -0400
files: tools/domctrl/console.c
description:
[ppc] allow for domctrl/console to send input and be non-blocking.
diff -r 31d379bde1a2490057f83367ee2e05693f479127 -r
7887529f51d9a223dee02d5ef3358123bed89958 tools/domctrl/console.c
--- a/tools/domctrl/console.c Tue May 16 15:58:05 2006 -0400
+++ b/tools/domctrl/console.c Tue May 16 15:59:32 2006 -0400
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <string.h>
#include <unistd.h>
+#include <signal.h>
#include <xen/dom0_ops.h>
#include <xen/io/console.h>
@@ -10,6 +11,14 @@
#include "domctrl.h"
+struct termios term_orig;
+static void term_restore(int sig)
+{
+ /* Restore original terminal attributes */
+ tcsetattr(STDIN_FILENO, TCSANOW, &term_orig);
+ exit(1);
+}
+
int console(char *argv[], int argc)
{
struct xencons_interface volatile *intf;
@@ -17,8 +26,9 @@ int console(char *argv[], int argc)
unsigned long domid;
unsigned long console_pfn;
unsigned long console_mfn;
+ long flgs;
int rc = 0;
-
+
if (argc < 2)
return -1;
@@ -45,11 +55,45 @@ int console(char *argv[], int argc)
}
DEBUG(printf("ringbuffer:\n"
+ " in_cons %x\n"
+ " in_prod %x\n"
" out_cons %x\n"
" out_prod %x\n",
+ intf->in_cons, intf->in_prod,
intf->out_cons, intf->out_prod));
+ /* start from the beging */
+ intf->out_cons = 0;
+
+ flgs = fcntl(STDIN_FILENO, F_GETFL);
+ if (flgs == -1) {
+ perror("getflgs");
+ exit(1);
+ }
+ if (fcntl(STDIN_FILENO, F_SETFL, flgs | O_NONBLOCK) == -1) {
+ perror("setflgs");
+ exit(1);
+ }
+
+ if (isatty(STDIN_FILENO)) {
+ struct sigaction sa;
+ struct termios term_raw;
+
+ DEBUG(printf("stdin is a tty\n"));
+ printf("Going raw: ^] will get you out\n");
+ tcgetattr(STDIN_FILENO, &term_orig);
+ term_raw = term_orig;
+ cfmakeraw(&term_raw);
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &term_raw) < 0) {
+ perror("tcsetattr() failed");
+ exit(1);
+ }
+ sa.sa_handler = term_restore;
+ sigaction(SIGTERM, &sa, NULL);
+ }
+
while (1) {
+ char buf[1];
XENCONS_RING_IDX cons, prod;
int size;
@@ -59,14 +103,36 @@ int console(char *argv[], int argc)
size = prod - cons;
if (!((size == 0) || (size > sizeof(intf->out)))) {
while (cons != prod) {
- char buf[1];
-
buf[0] = intf->out[MASK_XENCONS_IDX(cons++, intf->out)];
- write(STDOUT_FILENO, buf, 1);
+ /* making stdin nonblocking may have effected stdout */
+ for (;;) {
+ flgs = write(STDOUT_FILENO, buf, 1);
+ if (flgs == -1) {
+ perror("write");
+ exit(1);
+ } else if (flgs == 1) {
+ break;
+ }
+ usleep(1000);
+ }
}
intf->out_cons = cons;
}
- /* input here */
+ size = read(STDIN_FILENO, buf, 1);
+ if (size < 0 && errno != EAGAIN) {
+ perror("stdin");
+ exit(1);
+ } else if (size > 0) {
+ if (buf[0] == '\r')
+ write(STDOUT_FILENO, "\n", 1);
+ if (buf[0] == '\035') {
+ write(STDOUT_FILENO, "\n\r", 2);
+ term_restore(0);
+ }
+ write(STDOUT_FILENO, buf, 1);
+ intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] = buf[0];
+ ++intf->in_prod;
+ }
}
munmap(console, getpagesize());
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|