term: don't double fork new terminal windows

Instead, register their PIDs with the new reaper module and let it
handle them.
This commit is contained in:
Daniel Eklöf 2020-05-21 20:17:29 +02:00
parent f49742ebba
commit 789617d5ad
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 62 additions and 60 deletions

View file

@ -25,6 +25,8 @@
line is empty. line is empty.
* Number of lines to scroll is now always clamped to the number of * Number of lines to scroll is now always clamped to the number of
lines in the scrolling region.. lines in the scrolling region..
* New terminal windows spawned with `ctrl`+`shift`+`n` is no longer
double forked.
### Deprecated ### Deprecated

4
main.c
View file

@ -390,14 +390,14 @@ main(int argc, char *const *argv)
goto out; goto out;
if (!as_server && (term = term_init( if (!as_server && (term = term_init(
&conf, fdm, wayl, "foot", cwd, argc, argv, &conf, fdm, reaper, wayl, "foot", cwd, argc, argv,
&term_shutdown_cb, &shutdown_ctx)) == NULL) { &term_shutdown_cb, &shutdown_ctx)) == NULL) {
free(cwd); free(cwd);
goto out; goto out;
} }
free(cwd); free(cwd);
if (as_server && (server = server_init(&conf, fdm, wayl)) == NULL) if (as_server && (server = server_init(&conf, fdm, reaper, wayl)) == NULL)
goto out; goto out;
/* Remember to restore signals in slave */ /* Remember to restore signals in slave */

View file

@ -24,6 +24,7 @@ struct client;
struct server { struct server {
const struct config *conf; const struct config *conf;
struct fdm *fdm; struct fdm *fdm;
struct reaper *reaper;
struct wayland *wayl; struct wayland *wayl;
int fd; int fd;
@ -311,7 +312,7 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data)
client->conf.startup_mode = STARTUP_FULLSCREEN; client->conf.startup_mode = STARTUP_FULLSCREEN;
client->term = term_init( client->term = term_init(
&client->conf, server->fdm, server->wayl, &client->conf, server->fdm, server->reaper, server->wayl,
"footclient", cwd, argc, argv, &term_shutdown_handler, client); "footclient", cwd, argc, argv, &term_shutdown_handler, client);
if (client->term == NULL) { if (client->term == NULL) {
@ -406,7 +407,8 @@ err:
} }
struct server * struct server *
server_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl) server_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
struct wayland *wayl)
{ {
int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (fd == -1) { if (fd == -1) {
@ -448,6 +450,7 @@ server_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl)
*server = (struct server) { *server = (struct server) {
.conf = conf, .conf = conf,
.fdm = fdm, .fdm = fdm,
.reaper = reaper,
.wayl = wayl, .wayl = wayl,
.fd = fd, .fd = fd,

View file

@ -5,5 +5,6 @@
#include "wayland.h" #include "wayland.h"
struct server; struct server;
struct server *server_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl); struct server *server_init(const struct config *conf, struct fdm *fdm,
struct reaper *reaper, struct wayland *wayl);
void server_destroy(struct server *server); void server_destroy(struct server *server);

View file

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include "grid.h" #include "grid.h"
#include "quirks.h" #include "quirks.h"
#include "reaper.h"
#include "render.h" #include "render.h"
#include "selection.h" #include "selection.h"
#include "sixel.h" #include "sixel.h"
@ -714,8 +715,9 @@ load_fonts_from_conf(const struct terminal *term, const struct config *conf,
} }
struct terminal * struct terminal *
term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
const char *foot_exe, const char *cwd, int argc, char *const *argv, struct wayland *wayl, const char *foot_exe, const char *cwd,
int argc, char *const *argv,
void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data) void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data)
{ {
int ptmx = -1; int ptmx = -1;
@ -784,6 +786,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
/* Initialize configure-based terminal attributes */ /* Initialize configure-based terminal attributes */
*term = (struct terminal) { *term = (struct terminal) {
.fdm = fdm, .fdm = fdm,
.reaper = reaper,
.conf = conf, .conf = conf,
.quit = false, .quit = false,
.ptmx = ptmx, .ptmx = ptmx,
@ -2221,28 +2224,19 @@ term_flash(struct terminal *term, unsigned duration_ms)
bool bool
term_spawn_new(const struct terminal *term) term_spawn_new(const struct terminal *term)
{ {
pid_t pid = fork();
if (pid < 0) {
LOG_ERRNO("failed to fork new terminal");
return false;
}
if (pid == 0) {
/* Child */
int pipe_fds[2] = {-1, -1}; int pipe_fds[2] = {-1, -1};
if (pipe2(pipe_fds, O_CLOEXEC) < 0) { if (pipe2(pipe_fds, O_CLOEXEC) < 0) {
LOG_ERRNO("failed to create pipe"); LOG_ERRNO("failed to create pipe");
goto err; goto err;
} }
/* Double fork */ pid_t pid = fork();
pid_t pid2 = fork(); if (pid < 0) {
if (pid2 < 0) { LOG_ERRNO("failed to fork new terminal");
LOG_ERRNO("failed to double fork new terminal");
goto err; goto err;
} }
if (pid2 == 0) { if (pid == 0) {
/* Child */ /* Child */
close(pipe_fds[0]); close(pipe_fds[0]);
if (chdir(term->cwd) < 0 || if (chdir(term->cwd) < 0 ||
@ -2256,7 +2250,6 @@ term_spawn_new(const struct terminal *term)
} }
/* Parent */ /* Parent */
close(pipe_fds[1]); close(pipe_fds[1]);
int _errno; int _errno;
@ -2265,25 +2258,25 @@ term_spawn_new(const struct terminal *term)
ssize_t ret = read(pipe_fds[0], &_errno, sizeof(_errno)); ssize_t ret = read(pipe_fds[0], &_errno, sizeof(_errno));
close(pipe_fds[0]); close(pipe_fds[0]);
if (ret == 0) if (ret == 0) {
_exit(0); reaper_add(term->reaper, pid);
else if (ret < 0) return true;
} else if (ret < 0) {
LOG_ERRNO("failed to read from pipe"); LOG_ERRNO("failed to read from pipe");
else { return false;
} else {
LOG_ERRNO_P("%s: failed to spawn new terminal", _errno, term->foot_exe); LOG_ERRNO_P("%s: failed to spawn new terminal", _errno, term->foot_exe);
errno = _errno; errno = _errno;
waitpid(pid2, NULL, 0); waitpid(pid, NULL, 0);
return false;
} }
err: err:
if (pipe_fds[0] != -1) if (pipe_fds[0] != -1)
close(pipe_fds[0]); close(pipe_fds[0]);
_exit(errno); if (pipe_fds[1] != -1)
} close(pipe_fds[1]);
return false;
int result;
waitpid(pid, &result, 0);
return WIFEXITED(result) && WEXITSTATUS(result) == 0;
} }
void void

View file

@ -13,6 +13,7 @@
//#include "config.h" //#include "config.h"
#include "fdm.h" #include "fdm.h"
#include "reaper.h"
#include "wayland.h" #include "wayland.h"
#define likely(c) __builtin_expect(!!(c), 1) #define likely(c) __builtin_expect(!!(c), 1)
@ -206,6 +207,7 @@ enum term_surface {
struct terminal { struct terminal {
struct fdm *fdm; struct fdm *fdm;
struct reaper *reaper;
const struct config *conf; const struct config *conf;
pid_t slave; pid_t slave;
@ -439,8 +441,9 @@ struct terminal {
struct config; struct config;
struct terminal *term_init( struct terminal *term_init(
const struct config *conf, struct fdm *fdm, struct wayland *wayl, const struct config *conf, struct fdm *fdm, struct reaper *reaper,
const char *foot_exe, const char *cwd, int argc, char *const *argv, struct wayland *wayl, const char *foot_exe, const char *cwd,
int argc, char *const *argv,
void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data); void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data);
bool term_shutdown(struct terminal *term); bool term_shutdown(struct terminal *term);