+
+ /* If we get here, exec() failed */
+ exit(1);
+ }
+
+ /* Wait for our child to start the browser UI process and
+ for it to acquire the com.nokia.osso_browser D-Bus name,
+ then make the appropriate method call to open the browser
+ window. */
+ microb_start_dbus_watch_wait(raw_connection);
+ microb_start_dbus_watch_remove(raw_connection);
+ if (!launch_microb_open_window(ctx, uri, 0)) {
+ exit(1);
+ }
+
+ /* Workaround: the browser process we started is going to want
+ to hang around forever, hogging the com.nokia.osso_browser
+ D-Bus interface while at it. To fix this, we notice that
+ when the last browser window closes, the browser UI restarts
+ its attached browserd process. Get the browserd process's
+ PID and use ptrace() to watch for process termination.
+
+ This has the problem of not being able to detect whether
+ the bookmark window is open and/or in use, but it's the best
+ that I can think of. Better suggestions would be greatly
+ appreciated. */
+
+ /* Wait for the MicroB browserd lockfile to be created */
+ log_msg("Waiting for browserd lockfile to be created\n");
+ memset(buf, '\0', 256);
+ /* read() blocks until there are events to be read */
+ while ((bytes_read = read(fd, buf, 255)) > 0) {
+ pos = buf;
+ /* Loop until we see the event we're looking for
+ or until all the events are processed */
+ while (pos && (pos-buf) < bytes_read) {
+ event = (struct inotify_event *)pos;
+ len = sizeof(struct inotify_event) + event->len;
+ if (!strcmp(MICROB_LOCKFILE, event->name)) {
+ /* Lockfile created */
+ pos = NULL;
+ break;
+ } else if ((pos-buf) + len < bytes_read)
+ /* More events to process */
+ pos += len;
+ else
+ /* All events processed */
+ break;
+ }
+ if (!pos)
+ /* Event found, stop looking */
+ break;
+ memset(buf, '\0', 256);
+ }
+ inotify_rm_watch(fd, inot_wd);
+ close(fd);
+
+ /* Get the PID of the browserd from the lockfile */
+ if ((browserd_pid = get_browserd_pid(microb_lockfile)) <= 0) {
+ if (browserd_pid == 0)
+ log_msg("Profile lockfile link lacks PID\n");
+ else
+ log_perror(-browserd_pid,
+ "readlink() on lockfile failed");
+ exit(1);
+ }
+ free(microb_lockfile);
+
+ /* Wait for the browserd to close */
+ log_msg("Waiting for MicroB (browserd pid %d) to finish\n",
+ browserd_pid);
+ /* Clear any existing SIGCHLD handler to prevent interference
+ with our wait() */
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigemptyset(&(act.sa_mask));
+ if (sigaction(SIGCHLD, &act, &oldact) == -1) {
+ log_perror(errno, "clearing SIGCHLD handler failed");
+ exit(1);