Commit Diff


commit - f6d7d0475ffd7281ee039ca4089f12401e426bee
commit + bb28f1c2f6463f1e8881c90bb17a404cf7e5c3b7
blob - 63525147638b92ee324bb848ccd6309d709d80e5
blob + 30641668070413fbd954662660edc60a09fb2af6
--- fs.c
+++ fs.c
@@ -670,10 +670,93 @@ fs_init(void)
 
 	return 1;
 }
+
+/*
+ * Parse a line of the session file.  The format is:
+ *
+ *	URL [flags,...] [title]\n
+ */
+static void
+parse_session_line(char *line, const char **title, uint32_t *flags)
+{
+	char *s, *t, *ap;
+
+	*title = "";
+	*flags = 0;
+	if ((s = strchr(line, ' ')) == NULL)
+		return;
 
+	*s++ = '\0';
+
+	if ((t = strchr(s, ' ')) != NULL) {
+		*t++ = '\0';
+		*title = t;
+	}
+
+	while ((ap = strsep(&s, ",")) != NULL) {
+		if (!strcmp(ap, "current"))
+			*flags |= TAB_CURRENT;
+	}
+}
+
+static inline void
+sendtab(uint32_t flags, const char *uri, const char *title)
+{
+	struct session_tab tab;
+
+	memset(&tab, 0, sizeof(tab));
+	tab.flags = flags;
+
+	if (strlcpy(tab.uri, uri, sizeof(tab.uri)) >= sizeof(tab.uri))
+		return;
+
+	/* don't worry about cached title truncation */
+	if (title != NULL)
+		strlcpy(tab.title, title, sizeof(tab.title));
+
+	fs_send_ui(IMSG_SESSION_TAB, 0, -1, &tab, sizeof(tab));
+}
+
+static void
+load_last_session(int fd, short event, void *d)
+{
+	FILE		*session;
+	uint32_t	 flags;
+	size_t		 linesize = 0;
+	ssize_t		 linelen;
+	int		 first_time = 0;
+	const char	*title;
+	char		*nl, *line = NULL;
+
+	if ((session = fopen(session_file, "r")) == NULL) {
+		/* first time? */
+		first_time = 1;
+		goto end;
+	}
+
+	while ((linelen = getline(&line, &linesize, session)) != -1) {
+		if ((nl = strchr(line, '\n')) != NULL)
+			*nl = '\0';
+		parse_session_line(line, &title, &flags);
+		sendtab(flags, line, title);
+	}
+
+	fclose(session);
+	free(line);
+
+	if (last_time_crashed())
+		sendtab(TAB_CURRENT, "about:crash", NULL);
+
+end:
+	fs_send_ui(IMSG_SESSION_END, 0, -1, &first_time, sizeof(first_time));
+}
+
 int
 fs_main(void)
 {
+	struct event ev;
+	struct timeval t = {0, 0};
+
 	setproctitle("fs");
 
 	fs_init();
@@ -692,6 +775,14 @@ fs_main(void)
 
 	sandbox_fs_process();
 
+	/*
+	 * Run load_last_session during the event loop, as soon as
+	 * possible; it uses fs_send_ui so it can't be ran outside
+	 * of event_dispatch.
+	 */
+	evtimer_set(&ev, load_last_session, NULL);
+	evtimer_add(&ev, &t);
+
 	event_dispatch();
 	return 0;
 }
blob - 1f10db34c83843710bbab528a99c41ae2dc9b291
blob + ae4787379ee5e66cd0b232ed3091336387949b8d
--- fs.h
+++ fs.h
@@ -21,6 +21,14 @@
 
 #include <limits.h>
 
+#include "telescope.h"
+
+struct session_tab {
+	uint32_t	flags;
+	char		uri[GEMINI_URL_LEN];
+	char		title[TITLE_MAX];
+};
+
 extern char	config_path_base[PATH_MAX];
 extern char	data_path_base[PATH_MAX];
 extern char	cache_path_base[PATH_MAX];
blob - b7034636a85540f54593c139a16f93b797afc800
blob + 3ad12544f8771b00c748f3ca1e27e918f773996b
--- session.c
+++ session.c
@@ -133,84 +133,7 @@ save_session(void)
 	ui_send_fs(IMSG_SESSION_END, 0, NULL, 0);
 }
 
-/*
- * Parse a line of the session file.  The format is:
- *
- *	URL [flags,...] [title]\n
- */
-static void
-parse_session_line(char *line, const char **title, uint32_t *flags)
-{
-	char *s, *t, *ap;
-
-	*title = "";
-	*flags = 0;
-	if ((s = strchr(line, ' ')) == NULL)
-		return;
-
-	*s++ = '\0';
-
-	if ((t = strchr(s, ' ')) != NULL) {
-		*t++ = '\0';
-		*title = t;
-	}
-
-	while ((ap = strsep(&s, ",")) != NULL) {
-		if (*ap == '\0')
-			;
-		else if (!strcmp(ap, "current"))
-			*flags |= TAB_CURRENT;
-		else
-			message("unknown tab flag: %s", ap);
-	}
-}
-
 void
-load_last_session(void)
-{
-	const char	*title;
-	char		*nl, *line = NULL;
-	uint32_t	 flags;
-	size_t		 linesize = 0;
-	ssize_t		 linelen;
-	FILE		*session;
-	struct tab	*tab, *curr = NULL;
-
-	if ((session = fopen(session_file, "r")) == NULL) {
-		/* first time? */
-		new_tab("about:new", NULL, NULL);
-		switch_to_tab(new_tab("about:help", NULL, NULL));
-		return;
-	}
-
-	while ((linelen = getline(&line, &linesize, session)) != -1) {
-		if ((nl = strchr(line, '\n')) != NULL)
-			*nl = '\0';
-		parse_session_line(line, &title, &flags);
-		if ((tab = new_tab(line, NULL, NULL)) == NULL)
-			err(1, "new_tab");
-		strlcpy(tab->buffer.page.title, title,
-		    sizeof(tab->buffer.page.title));
-		if (flags & TAB_CURRENT)
-			curr = tab;
-	}
-
-	if (ferror(session))
-		message("error reading %s: %s",
-		    session_file, strerror(errno));
-	fclose(session);
-	free(line);
-
-	if (curr != NULL)
-		switch_to_tab(curr);
-
-	if (last_time_crashed())
-		switch_to_tab(new_tab("about:crash", NULL, NULL));
-
-	return;
-}
-
-void
 autosave_init(void)
 {
 	evtimer_set(&autosaveev, autosave_timer, NULL);
blob - 2edbfb2aba063787cb24e3822201c57e717314ff
blob + 4f9028a8885041034584872a9cedf4b1cfa8f33b
--- telescope.c
+++ telescope.c
@@ -45,6 +45,9 @@ static struct option longopts[] = {
 
 static const char *opts = "Cc:hnST:v";
 
+static int	has_url;
+static char	url[GEMINI_URL_LEN];
+
 /*
  * Used to know when we're finished loading.
  */
@@ -114,6 +117,7 @@ static void		 handle_imsg_eof(struct imsg *, size_t);
 static void		 handle_imsg_bookmark_ok(struct imsg *, size_t);
 static void		 handle_imsg_save_cert_ok(struct imsg *, size_t);
 static void		 handle_imsg_update_cert_ok(struct imsg *, size_t);
+static void		 handle_imsg_session(struct imsg *, size_t);
 static void		 handle_dispatch_imsg(int, short, void *);
 static int		 load_about_url(struct tab *, const char *);
 static int		 load_file_url(struct tab *, const char *);
@@ -152,6 +156,8 @@ static imsg_handlerfn *handlers[] = {
 	[IMSG_SAVE_CERT_OK] = handle_imsg_save_cert_ok,
 	[IMSG_UPDATE_CERT_OK] = handle_imsg_update_cert_ok,
 	[IMSG_FILE_OPENED] = handle_imsg_file_opened,
+	[IMSG_SESSION_TAB] = handle_imsg_session,
+	[IMSG_SESSION_END] = handle_imsg_session,
 };
 
 static struct ohash	certs;
@@ -484,7 +490,52 @@ handle_imsg_file_opened(struct imsg *imsg, size_t data
 	} else {
 		d->fd = imsg->fd;
 		ui_send_net(IMSG_PROCEED, d->id, NULL, 0);
+	}
+}
+
+static void
+handle_imsg_session(struct imsg *imsg, size_t datalen)
+{
+	static struct tab	*curr;
+	struct session_tab	 st;
+	struct tab		*tab;
+	int			 first_time;
+
+	/*
+	 * The fs process tried to send tabs after it has announced
+	 * that he's done.  Something fishy is going on, better die.
+	 */
+	if (operating)
+		die();
+
+	if (imsg->hdr.type == IMSG_SESSION_END) {
+		if (datalen != sizeof(first_time))
+			die();
+		memcpy(&first_time, imsg->data, sizeof(first_time));
+		if (first_time) {
+			new_tab("about:new", NULL, NULL);
+			curr = new_tab("about:help", NULL, NULL);
+		}
+
+		operating = 1;
+		if (curr != NULL)
+			switch_to_tab(curr);
+		if (has_url || TAILQ_EMPTY(&tabshead))
+			new_tab(url, NULL, NULL);
+		ui_main_loop();
+		return;
 	}
+
+	if (datalen != sizeof(st))
+		die();
+
+	memcpy(&st, imsg->data, sizeof(st));
+	if ((tab = new_tab(st.uri, NULL, NULL)) == NULL)
+		die();
+	strlcpy(tab->buffer.page.title, st.title,
+	    sizeof(tab->buffer.page.title));
+	if (st.flags & TAB_CURRENT)
+		curr = tab;
 }
 
 static void
@@ -1043,11 +1094,9 @@ main(int argc, char * const *argv)
 	pid_t		 pid;
 	int		 pipe2net[2], pipe2fs[2];
 	int		 ch, configtest = 0, fail = 0;
-	int		 has_url = 0;
 	int		 proc = -1;
 	int		 sessionfd = -1;
 	int		 status;
-	char		 url[GEMINI_URL_LEN+1];
 	const char	*argv0;
 
 	argv0 = argv[0];
@@ -1173,15 +1222,10 @@ main(int argc, char * const *argv)
 	event_set(&iev_net->ev, iev_net->ibuf.fd, iev_net->events,
 	    iev_net->handler, iev_net);
 	event_add(&iev_net->ev, NULL);
-
-	if (ui_init()) {
-		load_last_session();
-		if (has_url || TAILQ_EMPTY(&tabshead))
-			new_tab(url, NULL, NULL);
 
+	if (ui_init()) {
 		sandbox_ui_process();
-		operating = 1;
-		ui_main_loop();
+		event_dispatch();
 		ui_end();
 	}
 
blob - a65d8fc55b74fe967265c95eb0f0a8210fc24a73
blob + 6c4ec8569884c64061a1e3ea38634184eef8f1f7
--- telescope.h
+++ telescope.h
@@ -28,6 +28,7 @@
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 #define GEMINI_URL_LEN 1024
+#define TITLE_MAX 128+1		/* account for NUL too */
 
 #define SIDE_WINDOW_LEFT	0x1
 #define SIDE_WINDOW_BOTTOM	0x2
blob - e5e0361f33bc5c78ca6c96f2a7782d4aabcee71d
blob + c6e8940d36967286098b21c39b48954d8ae5d63e
--- ui.c
+++ ui.c
@@ -1121,6 +1121,12 @@ ui_init()
 
 	mvwprintw(body, 0, 0, "");
 
+	return 1;
+}
+
+void
+ui_main_loop(void)
+{
 	evtimer_set(&resizeev, handle_resize, NULL);
 
 	event_set(&stdioev, 0, EV_READ | EV_PERSIST, dispatch_stdio, NULL);
@@ -1128,17 +1134,9 @@ ui_init()
 
 	signal_set(&winchev, SIGWINCH, handle_resize, NULL);
 	signal_add(&winchev, NULL);
-
-	return 1;
-}
 
-void
-ui_main_loop(void)
-{
 	switch_to_tab(current_tab);
 	rearrange_windows();
-
-	event_dispatch();
 }
 
 void