commit bb28f1c2f6463f1e8881c90bb17a404cf7e5c3b7 from: Omar Polo date: Thu Dec 30 17:18:05 2021 UTC move parse_last_session to the fs process ~/.telescope/session was parsed in the main process before dropping in the sandbox: that's no good. This moves the initialization of the ui events later in ui_main_loop and makes so that the fs process, after entering the sandbox, parses and sends the content of the last session back to the main process; when it's done the ui gets loaded and telescope is back rocking. I'm plannig to re-use the struct session_tab during the save session operation soon. 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 +#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