Commit Diff


commit - 5163d06e99f13dc060058f5ca99383f1442a504a
commit + 6cc5fcfe173c6d504497dead4171fabf46131134
blob - 9d66121a1ab68547730a8417a7f72de2c9be8c61
blob + cdf12dd6406e0ec32f1506e1a0aed23f545b3ae3
--- ChangeLog
+++ ChangeLog
@@ -1,5 +1,7 @@
 2021-07-08  Omar Polo  <op@omarpolo.com>
 
+	* telescope.c (start_child): re-exec the children processes
+
 	* ui.c (print_vline): bug: print the trailing face until the right column, not one less.  (this would leave the last column white if !olivetti-mode and a background color for some body lines)
 
 2021-07-07  Omar Polo  <op@omarpolo.com>
blob - 30c46ecda4c84c1859d216abd5479f7583308c0b
blob + 676cd6ff61373fc0d64c1bcbcbbc1cdacb2a405b
--- fs.c
+++ fs.c
@@ -350,12 +350,17 @@ fs_init(void)
 }
 
 int
-fs_main(struct imsgbuf *b)
+fs_main(void)
 {
-	ibuf = b;
+	setproctitle("fs");
 
+	fs_init();
+
 	event_init();
 
+	if ((ibuf = calloc(1, sizeof(*ibuf))) == NULL)
+		die();
+	imsg_init(ibuf, 3);
 	event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, handle_dispatch_imsg, ibuf);
 	event_add(&imsgev, NULL);
 
blob - 7b089c544b5ccfbe0f56de616faaed19061e60ab
blob + dd48075995c32948a8f2168e23404814ca966cc1
--- gemini.c
+++ gemini.c
@@ -569,9 +569,9 @@ handle_dispatch_imsg(int fd, short ev, void *d)
 }
 
 int
-client_main(struct imsgbuf *b)
+client_main(void)
 {
-	ibuf = b;
+	setproctitle("net");
 
 	TAILQ_INIT(&reqhead);
 
@@ -582,6 +582,10 @@ client_main(struct imsgbuf *b)
 
 	event_init();
 
+	/* Setup pipe and event handler to the main process */
+	if ((ibuf = calloc(1, sizeof(*ibuf))) == NULL)
+		die();
+	imsg_init(ibuf, 3);
 	event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, handle_dispatch_imsg, ibuf);
 	event_add(&imsgev, NULL);
 
blob - f3bdd4d8240930703a31bcec2934ff54fc8dc851
blob + 1e9b1046ee0786259437ad3757cd7caa436e1505
--- telescope.c
+++ telescope.c
@@ -13,6 +13,12 @@
 struct event		 netev, fsev;
 struct tabshead		 tabshead;
 struct proxylist	 proxies;
+
+enum telescope_process {
+	PROC_UI,
+	PROC_FS,
+	PROC_NET,
+};
 
 /* the first is also the fallback one */
 static struct proto protos[] = {
@@ -42,6 +48,7 @@ static void		 handle_imsg_update_cert_ok(struct imsg *
 static void		 handle_dispatch_imsg(int, short, void*);
 static void		 load_page_from_str(struct tab*, const char*);
 static void		 do_load_url(struct tab*, const char*);
+static pid_t		 start_child(enum telescope_process, const char *, int);
 
 static imsg_handlerfn *handlers[] = {
 	[IMSG_ERR] = handle_imsg_err,
@@ -680,11 +687,49 @@ session_new_tab_cb(const char *url)
 	new_tab(url);
 }
 
-static void
-usage(void)
+static pid_t
+start_child(enum telescope_process p, const char *argv0, int fd)
+{
+	const char	*argv[4];
+	int		 argc = 0;
+	pid_t		 pid;
+
+	switch (pid = fork()) {
+	case -1:
+		die();
+	case 0:
+		break;
+	default:
+		close(fd);
+		return pid;
+	}
+
+	if (dup2(fd, 3) == -1)
+		err(1, "cannot setup imsg fd");
+
+	argv[argc++] = argv0;
+	switch (p) {
+	case PROC_UI:
+		errx(1, "Can't start ui process");
+	case PROC_FS:
+		argv[argc++] = "-Tf";
+		break;
+	case PROC_NET:
+		argv[argc++] = "-Tn";
+		break;
+	}
+
+	argv[argc++] = NULL;
+	execvp(argv0, (char *const *)argv);
+	err(1, "execvp(%s)", argv0);
+}
+
+static void __attribute__((noreturn))
+usage(int r)
 {
 	fprintf(stderr, "USAGE: %s [-hn] [-c config] [url]\n", getprogname());
 	fprintf(stderr, "version: " PACKAGE " " VERSION "\n");
+	exit(r);
 }
 
 int
@@ -694,9 +739,13 @@ main(int argc, char * const *argv)
 	int		 net_fds[2], fs_fds[2];
 	int		 ch, configtest = 0, fail = 0;
 	int		 has_url = 0;
+	int		 proc = -1;
 	char		 path[PATH_MAX];
-	char		*url = NEW_TAB_URL;
+	const char	*url = NEW_TAB_URL;
+	const char	*argv0;
 
+	argv0 = argv[0];
+
 	signal(SIGCHLD, SIG_IGN);
 	signal(SIGPIPE, SIG_IGN);
 
@@ -706,7 +755,7 @@ main(int argc, char * const *argv)
 	strlcpy(path, getenv("HOME"), sizeof(path));
 	strlcat(path, "/.telescope/config", sizeof(path));
 
-	while ((ch = getopt(argc, argv, "c:hn")) != -1) {
+	while ((ch = getopt(argc, argv, "c:hnT:")) != -1) {
 		switch (ch) {
 		case 'c':
 			fail = 1;
@@ -716,28 +765,44 @@ main(int argc, char * const *argv)
 			configtest = 1;
 			break;
 		case 'h':
-			usage();
-			return 0;
+			usage(0);
+		case 'T':
+			switch (*optarg) {
+			case 'f':
+				proc = PROC_FS;
+				break;
+			case 'n':
+				proc = PROC_NET;
+				break;
+			default:
+				errx(1, "invalid process spec %c",
+				    *optarg);
+			}
+			break;
 		default:
-			usage();
-			return 1;
+			usage(1);
 		}
 	}
 
 	argc -= optind;
 	argv += optind;
 
+	if (proc != -1) {
+		if (argc > 0)
+			usage(1);
+		else if (proc == PROC_FS)
+			return fs_main();
+		else if (proc == PROC_NET)
+			return client_main();
+		else
+			usage(1);
+	}
+
 	if (argc != 0) {
 		has_url = 1;
 		url = argv[0];
 	}
 
-	/*
-	 * initialize part of the fs layer.  Before starting the UI
-	 * and dropping the priviledges we need to read some stuff.
-	 */
-	fs_init();
-
 	/* setup keys before reading the config */
 	TAILQ_INIT(&global_map.m);
 	global_map.unhandled_input = global_key_unbound;
@@ -750,45 +815,23 @@ main(int argc, char * const *argv)
 		exit(0);
 	}
 
+	/* Start children. */
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fs_fds) == -1)
 		err(1, "socketpair");
+	start_child(PROC_FS, argv0, fs_fds[1]);
+	imsg_init(&fs_ibuf, fs_fds[0]);
+	fsibuf = &fs_ibuf;
 
-	switch (fork()) {
-	case -1:
-		err(1, "fork");
-	case 0:
-		/* child */
-		setproctitle("fs");
-		close(fs_fds[0]);
-		imsg_init(&fs_ibuf, fs_fds[1]);
-		exit(fs_main(&fs_ibuf));
-	default:
-		close(fs_fds[1]);
-		imsg_init(&fs_ibuf, fs_fds[0]);
-		fsibuf = &fs_ibuf;
-	}
-
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, net_fds) == -1)
 		err(1, "socketpair");
+	start_child(PROC_NET, argv0, net_fds[1]);
+	imsg_init(&network_ibuf, net_fds[0]);
+	netibuf = &network_ibuf;
 
-	switch (fork()) {
-	case -1:
-		err(1, "fork");
-	case 0:
-		/* child */
-		setproctitle("client");
-		close(net_fds[0]);
-		close(fs_fds[0]);
-		imsg_init(&network_ibuf, net_fds[1]);
-		exit(client_main(&network_ibuf));
-	default:
-		close(net_fds[1]);
-		imsg_init(&network_ibuf, net_fds[0]);
-		netibuf = &network_ibuf;
-	}
-
 	setproctitle("ui");
 
+	/* initialize tofu & load certificates */
+	fs_init();
 	tofu_init(&certs, 5, offsetof(struct tofu_entry, domain));
 	load_certs(&certs);
 
blob - 82231939a93f4c0b653475c37143c471303d7876
blob + 17475e59659c68fa7e64a500759111da5ddce936
--- telescope.h
+++ telescope.h
@@ -321,12 +321,12 @@ void		 config_apply_style(void);
 
 /* fs.c */
 int		 fs_init(void);
-int		 fs_main(struct imsgbuf*);
+int		 fs_main(void);
 int		 load_certs(struct ohash*);
 int		 load_last_session(void(*)(const char*));
 
 /* gemini.c */
-int		 client_main(struct imsgbuf*);
+int		 client_main(void);
 
 /* gemtext.c */
 void		 gemtext_initparser(struct parser*);