Hi Dan, On Fri, 2007-03-02 at 14:35 +0000, Daniel P. Berrange wrote: > > +static int qemudOpenMonitor(struct qemud_vm *vm, const char *monitor) > { #define MONITOR_POLL_TIMEOUT 5 > + int monfd; > + char buffer[1024]; > + int got = 0; > + > + if (!(monfd = open(monitor, O_RDWR))) { > + return -1; > + } > + if (qemudSetCloseExec(monfd) < 0) > + goto error; > + if (qemudSetNonBlock(monfd) < 0) > + goto error; > + > + /* Consume & discard the initial greeting */ > + for(;;) { > + int ret; > + > + ret = read(monfd, buffer+got, sizeof(buffer)-got-1); What happens if the buffer fills up ? > + if (ret == 0) > + goto error; > + if (ret < 0) { > + struct pollfd fd = { .fd = monfd, .events = POLLIN }; > + if (errno != EAGAIN && > + errno != EINTR) > + goto error; > + > + ret = poll(&fd, 1, 5); ret = poll(&fd, 1, MONITOR_POLL_TIMEOUT); Giving up after 5 milliseconds? Are we that afraid of commitment? > +static int qemudWaitForMonitor(struct qemud_vm *vm) { We don't set an error in here, so how about returning the appropriate errno from the function? > + char buffer[1024]; /* Plenty of space to get startup greeting */ > + int got = 0; > + > + for (;;) { > + int ret; > + > + ret = read(vm->stderr, buffer+got, sizeof(buffer)-got-1); > + if (ret == 0) { > + return -1; > + } > + if (ret < 0) { > + struct pollfd fd = { .fd = vm->stderr, .events = > POLLIN }; > + if (errno != EAGAIN && > + errno != EINTR) { > + return -1; > + } > + > + ret = poll(&fd, 1, 5000); Again, a #define for the timeout would be nice > + if (ret == 0) { > + return -1; > + } else if (ret < 0) { > + if (errno != EINTR) > + return -1; > + } else if (fd.revents != POLLIN) { > + return -1; > + } > + } else { > + char monitor[100]; > + char *tmp = buffer; > + got += ret; > + buffer[got] = '\0'; > + while (tmp && *tmp) { > + if (sscanf(tmp, "char device redirected to %19s", monitor) == 1) { Path length of 100, maximum field with of 19? That's all rather voodooish ... hope about strstr() to find it, buffer length of PATH_MAX and then just strncpy()? Also, it'd be nice to split that out into e.g. qemudMonitorPathFromStr(buffer, monitorPath, PATH_MAX) > + if (qemudOpenMonitor(vm, monitor) < 0) > + return -1; > + return 0; > + } > + tmp = index(tmp, '\n'); index() is a bit odd, why not strstr() ? > +static int qemudNextFreeVNCPort(struct qemud_server *server > ATTRIBUTE_UNUSED) { I don't really know the context, but it'd be much nicer if we could just QEMU find a free port itself and then we query the port - e.g. the obvious race condition. > + int i; > + > + for (i = 5900 ; i < 6000 ; i++) { > + int fd; > + struct sockaddr_in addr; > + addr.sin_family = AF_INET; > + addr.sin_port = htons(i); > + addr.sin_addr.s_addr = htonl(INADDR_ANY); > + fd = socket(PF_INET, SOCK_STREAM, 0); > + if (fd < 0) > + return -1; > + > + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) Um, why not bind() (with SO_REUSEADDR)? > ret = 0; > + > + if (qemudWaitForMonitor(vm) < 0) { Set an error based on the returned errno ... > struct qemud_vm *next = vm->next; > @@ -1356,6 +1426,7 @@ static int qemudDispatchPoll(struct qemu > if (stderrfd != -1) { > if (!failed) { > if (fds[fd].revents) { > + printf("%d\n", fds[fd].revents); Kill this Cheers, Mark.