- /* 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, which causes an observable
- change in the ownership of the Mozilla.MicroB D-Bus name.
- Watch for this change and kill off the browser UI process
- when it happens.
-
- 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. */
- kill_microb = 0;
- dbus_bus_add_match(raw_connection,
- "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='Mozilla.MicroB'",
- &dbus_error);
- if (dbus_error_is_set(&dbus_error)) {
- fprintf(stderr,
- "Failed to set up watch for browserd restart: %s\n",
- dbus_error.message);
- dbus_error_free(&dbus_error);
- exit(1);
- }
- /* Maemo 5 PR1.1 seems to have changed the name browserd takes
- to com.nokia.microb-engine; look for this too */
- dbus_bus_add_match(raw_connection,
- "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='com.nokia.microb-engine'",
- &dbus_error);
- if (dbus_error_is_set(&dbus_error)) {
- fprintf(stderr,
- "Failed to set up watch for browserd restart: %s\n",
- dbus_error.message);
- dbus_error_free(&dbus_error);
- exit(1);
+ return 1;
+}
+
+/* Launch Fremantle MicroB and kill it when the session is finished */
+void launch_microb_fremantle_with_kill(struct swb_context *ctx, char *uri) {
+ int status;
+ pid_t pid;
+ char *homedir, *microb_profile_dir, *microb_lockfile;
+ size_t len;
+ int fd, inot_wd;
+ DBusConnection *raw_connection;
+ int bytes_read;
+ char buf[256], *pos;
+ struct inotify_event *event;
+ pid_t browserd_pid, waited_pid;
+ struct sigaction act, oldact;
+ int ignore_sigstop;
+
+ /* Put together the path to the MicroB browserd lockfile */
+ if (!(homedir = getenv("HOME")))
+ homedir = DEFAULT_HOMEDIR;
+ len = strlen(homedir) + strlen(MICROB_PROFILE_DIR) + 1;
+ if (!(microb_profile_dir = calloc(len, sizeof(char)))) {
+ log_msg("calloc() failed\n");
+ exit(1);
+ }
+ snprintf(microb_profile_dir, len, "%s%s",
+ homedir, MICROB_PROFILE_DIR);
+ len = strlen(homedir) + strlen(MICROB_PROFILE_DIR) +
+ strlen("/") + strlen(MICROB_LOCKFILE) + 1;
+ if (!(microb_lockfile = calloc(len, sizeof(char)))) {
+ log_msg("calloc() failed\n");
+ exit(1);
+ }
+ snprintf(microb_lockfile, len, "%s%s/%s",
+ homedir, MICROB_PROFILE_DIR, MICROB_LOCKFILE);
+
+ /* Watch for the creation of a MicroB browserd lockfile
+ NB: The watch has to be set up here, before the browser
+ is launched, to make sure there's no race between browserd
+ starting and us creating the watch */
+ if ((fd = inotify_init()) == -1) {
+ log_perror(errno, "inotify_init");
+ exit(1);
+ }
+ if ((inot_wd = inotify_add_watch(fd, microb_profile_dir,
+ IN_CREATE)) == -1) {
+ log_perror(errno, "inotify_add_watch");
+ exit(1);
+ }
+ free(microb_profile_dir);
+
+ /* Set up the D-Bus eavesdropping we'll use to watch for MicroB
+ acquiring the com.nokia.osso_browser D-Bus name. Again, this needs
+ to happen before the browser is launched, so that there's no race
+ between establishing the watch and browser startup. */
+ if (!(raw_connection = microb_start_dbus_watch_init())) {
+ exit(1);
+ }
+
+ /* Launch a MicroB browser process if it's not already running */
+ if ((pid = launch_microb_start_browser_process(raw_connection, fd)) < 0)
+ exit(1);
+
+ /* Release the osso_browser D-Bus name so that MicroB can take it */
+ dbus_release_osso_browser_name(ctx);
+
+ /* 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. */
+
+ if (!pid)
+ /* If we didn't start the MicroB browser process ourselves, try
+ to get the PID of the browserd from the lockfile */
+ browserd_pid = get_browserd_pid(microb_lockfile);
+ else
+ browserd_pid = 0;
+
+ /* If getting the lockfile PID failed, or the lockfile PID doesn't
+ exist, assume that we have a stale lockfile and wait for the new
+ browserd lockfile to be created */
+ if (browserd_pid <= 0 || kill(browserd_pid, 0) == ESRCH) {
+ 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);