mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-29 07:58:01 -04:00
term: move client startup to a new function, slave_spawn()
This commit is contained in:
parent
348f3738da
commit
18921f7f45
3 changed files with 79 additions and 61 deletions
72
slave.c
72
slave.c
|
|
@ -1,9 +1,10 @@
|
||||||
#define _XOPEN_SOURCE 500
|
#define _XOPEN_SOURCE 500
|
||||||
#include "slave.h"
|
#include "slave.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
@ -12,7 +13,9 @@
|
||||||
#define LOG_ENABLE_DBG 0
|
#define LOG_ENABLE_DBG 0
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
void
|
#include "tokenize.h"
|
||||||
|
|
||||||
|
static void
|
||||||
slave_exec(int ptmx, char *const argv[], int err_fd)
|
slave_exec(int ptmx, char *const argv[], int err_fd)
|
||||||
{
|
{
|
||||||
int pts = -1;
|
int pts = -1;
|
||||||
|
|
@ -62,3 +65,68 @@ err:
|
||||||
close(ptmx);
|
close(ptmx);
|
||||||
_exit(errno);
|
_exit(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
slave_spawn(int ptmx, int argc, char *const *argv,
|
||||||
|
const char *conf_shell)
|
||||||
|
{
|
||||||
|
int fork_pipe[2];
|
||||||
|
if (pipe2(fork_pipe, O_CLOEXEC) < 0) {
|
||||||
|
LOG_ERRNO("failed to create pipe");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
LOG_ERRNO("failed to fork");
|
||||||
|
close(fork_pipe[0]);
|
||||||
|
close(fork_pipe[1]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
/* Child */
|
||||||
|
close(fork_pipe[0]); /* Close read end */
|
||||||
|
|
||||||
|
char **_shell_argv = NULL;
|
||||||
|
char *const *shell_argv = argv;
|
||||||
|
|
||||||
|
if (argc == 0) {
|
||||||
|
char *shell_copy = strdup(conf_shell);
|
||||||
|
if (!tokenize_cmdline(shell_copy, &_shell_argv)) {
|
||||||
|
free(shell_copy);
|
||||||
|
(void)!write(fork_pipe[1], &errno, sizeof(errno));
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
shell_argv = _shell_argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
slave_exec(ptmx, shell_argv, fork_pipe[1]);
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
close(fork_pipe[1]); /* Close write end */
|
||||||
|
LOG_DBG("slave has PID %d", term->slave);
|
||||||
|
|
||||||
|
int _errno;
|
||||||
|
static_assert(sizeof(errno) == sizeof(_errno), "errno size mismatch");
|
||||||
|
|
||||||
|
ssize_t ret = read(fork_pipe[0], &_errno, sizeof(_errno));
|
||||||
|
close(fork_pipe[0]);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERRNO("failed to read from pipe");
|
||||||
|
return -1;
|
||||||
|
} else if (ret == sizeof(_errno)) {
|
||||||
|
LOG_ERRNO(
|
||||||
|
"%s: failed to execute", argc == 0 ? conf_shell : argv[0]);
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
LOG_DBG("%s: successfully started", conf->shell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
|
||||||
5
slave.h
5
slave.h
|
|
@ -1,4 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
void slave_exec(int ptmx, char *const argv[], int err_fd);
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
pid_t slave_spawn(
|
||||||
|
int ptmx, int argc, char *const *argv, const char *conf_shell);
|
||||||
|
|
|
||||||
63
terminal.c
63
terminal.c
|
|
@ -20,7 +20,6 @@
|
||||||
#include "vt.h"
|
#include "vt.h"
|
||||||
#include "selection.h"
|
#include "selection.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "tokenize.h"
|
|
||||||
#include "slave.h"
|
#include "slave.h"
|
||||||
|
|
||||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
@ -326,6 +325,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
goto close_fds;
|
goto close_fds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize configure-based terminal attributes */
|
||||||
term = malloc(sizeof(*term));
|
term = malloc(sizeof(*term));
|
||||||
*term = (struct terminal) {
|
*term = (struct terminal) {
|
||||||
.fdm = fdm,
|
.fdm = fdm,
|
||||||
|
|
@ -410,6 +410,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
term->cell_height = (int)ceil(term->fextents.height);
|
term->cell_height = (int)ceil(term->fextents.height);
|
||||||
LOG_INFO("cell width=%d, height=%d", term->cell_width, term->cell_height);
|
LOG_INFO("cell width=%d, height=%d", term->cell_width, term->cell_height);
|
||||||
|
|
||||||
|
/* Initiailze the Wayland window backend */
|
||||||
if ((term->window = wayl_win_init(wayl)) == NULL)
|
if ((term->window = wayl_win_init(wayl)) == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|
@ -431,63 +432,9 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
height = max(height, term->cell_height);
|
height = max(height, term->cell_height);
|
||||||
render_resize(term, width, height);
|
render_resize(term, width, height);
|
||||||
|
|
||||||
{
|
/* Start the slave/client */
|
||||||
int fork_pipe[2];
|
if (!slave_spawn(term->ptmx, argc, argv, conf->shell))
|
||||||
if (pipe2(fork_pipe, O_CLOEXEC) < 0) {
|
goto err;
|
||||||
LOG_ERRNO("failed to create pipe");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
term->slave = fork();
|
|
||||||
switch (term->slave) {
|
|
||||||
case -1:
|
|
||||||
LOG_ERRNO("failed to fork");
|
|
||||||
close(fork_pipe[0]);
|
|
||||||
close(fork_pipe[1]);
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
/* Child */
|
|
||||||
close(fork_pipe[0]); /* Close read end */
|
|
||||||
|
|
||||||
char **_shell_argv = NULL;
|
|
||||||
char *const *shell_argv = argv;
|
|
||||||
|
|
||||||
if (argc == 0) {
|
|
||||||
if (!tokenize_cmdline(conf->shell, &_shell_argv)) {
|
|
||||||
(void)!write(fork_pipe[1], &errno, sizeof(errno));
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
shell_argv = _shell_argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
slave_exec(ptmx, shell_argv, fork_pipe[1]);
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
close(fork_pipe[1]); /* Close write end */
|
|
||||||
LOG_DBG("slave has PID %d", term->slave);
|
|
||||||
|
|
||||||
int _errno;
|
|
||||||
static_assert(sizeof(errno) == sizeof(_errno), "errno size mismatch");
|
|
||||||
|
|
||||||
ssize_t ret = read(fork_pipe[0], &_errno, sizeof(_errno));
|
|
||||||
close(fork_pipe[0]);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERRNO("failed to read from pipe");
|
|
||||||
goto err;
|
|
||||||
} else if (ret == sizeof(_errno)) {
|
|
||||||
LOG_ERRNO(
|
|
||||||
"%s: failed to execute", argc == 0 ? conf->shell : argv[0]);
|
|
||||||
goto err;
|
|
||||||
} else
|
|
||||||
LOG_DBG("%s: successfully started", conf->shell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read logic requires non-blocking mode */
|
/* Read logic requires non-blocking mode */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue