+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, unixsock, UNIX_PATH_MAX);
+ addr.sun_path[UNIX_PATH_MAX-1] = '\0';
+
+ tries = 100;
+ while (tries > 0) {
+ /* Always sleep at least once to give qemu a small chance to start up. */
+ usleep (10000);
+
+ r = connect (g->sock, (struct sockaddr *) &addr, sizeof addr);
+ if ((r == -1 && errno == EINPROGRESS) || r == 0)
+ goto connected;
+
+ perrorf (g, "connect");
+ tries--;
+ }
+
+ error (g, "failed to connect to vmchannel socket");
+ goto cleanup2;
+
+ connected:
+ /* Watch the file descriptors. */
+ g->stdout_watch =
+ main_loop.add_handle (g, g->fd[1],
+ GUESTFS_HANDLE_READABLE,
+ stdout_event, g);
+ if (g->stdout_watch == -1) {
+ error (g, "could not watch qemu stdout");
+ goto cleanup3;
+ }
+
+ g->sock_watch =
+ main_loop.add_handle (g, g->sock,
+ GUESTFS_HANDLE_READABLE |
+ GUESTFS_HANDLE_HANGUP |
+ GUESTFS_HANDLE_ERROR,
+ sock_read_event, g);
+ if (g->sock_watch == -1) {
+ error (g, "could not watch daemon communications socket");
+ goto cleanup3;
+ }
+
+ g->state = LAUNCHING;
+ return 0;
+
+ cleanup3:
+ if (g->stdout_watch >= 0)
+ main_loop.remove_handle (g, g->stdout_watch);
+ if (g->sock_watch >= 0)
+ main_loop.remove_handle (g, g->sock_watch);
+
+ cleanup2:
+ close (g->sock);
+
+ cleanup1:
+ close (wfd[1]);
+ close (rfd[0]);
+ kill (g->pid, 9);
+ waitpid (g->pid, NULL, 0);
+ g->fd[0] = -1;
+ g->fd[1] = -1;
+ g->sock = -1;
+ g->pid = 0;
+ g->start_t = 0;
+ g->stdout_watch = -1;
+ g->sock_watch = -1;
+ return -1;
+}
+
+static void
+finish_wait_ready (guestfs_h *g, void *vp)
+{
+ *((int *)vp) = 1;
+ main_loop.main_loop_quit (g);
+}