From b5efe984bbfec151b70d3450f4f18243313de497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 20 Feb 2020 18:36:09 +0100 Subject: [PATCH] slave: prefix argv[0] with a '-' when spawning a login-shell --- client.c | 6 ++++++ main.c | 3 ++- server.c | 5 ++++- slave.c | 31 ++++++++++++++++++++++++++----- slave.h | 2 +- terminal.c | 6 +++--- terminal.h | 4 ++-- 7 files changed, 44 insertions(+), 13 deletions(-) diff --git a/client.c b/client.c index de7c6c6f..e00adc40 100644 --- a/client.c +++ b/client.c @@ -161,6 +161,7 @@ main(int argc, char *const *argv) /* Calculate total length */ total_len += sizeof(cwd_len) + cwd_len; total_len += sizeof(term_len) + term_len; + total_len += sizeof(uint8_t); /* login_shell */ total_len += sizeof(argc); for (int i = 0; i < argc; i++) { @@ -190,6 +191,11 @@ main(int argc, char *const *argv) goto err; } + if (send(fd, &(uint8_t){login_shell}, sizeof(uint8_t), 0) != sizeof(uint8_t)) { + LOG_ERRNO("failed to send login-shell"); + goto err; + } + LOG_DBG("argc = %d", argc); if (send(fd, &argc, sizeof(argc), 0) != sizeof(argc)) { LOG_ERRNO("failed to send argc/argv to server"); diff --git a/main.c b/main.c index 878db875..7709e05c 100644 --- a/main.c +++ b/main.c @@ -332,7 +332,8 @@ main(int argc, char *const *argv) goto out; if (!as_server && (term = term_init( - &conf, fdm, wayl, conf.term, "foot", cwd, argc, argv, + &conf, fdm, wayl, conf.term, conf.login_shell, + "foot", cwd, argc, argv, &term_shutdown_cb, &shutdown_ctx)) == NULL) { free(cwd); goto out; diff --git a/server.c b/server.c index 92f326a0..dc0b1e47 100644 --- a/server.c +++ b/server.c @@ -213,6 +213,9 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data) goto shutdown; } + CHECK_BUF(sizeof(uint8_t)); + const uint8_t login_shell = *(const uint8_t *)p; p += sizeof(login_shell); + CHECK_BUF(sizeof(argc)); argc = *(int *)p; p += sizeof(argc); argv = calloc(argc + 1, sizeof(argv[0])); @@ -238,7 +241,7 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data) client->term = term_init( server->conf, server->fdm, server->wayl, - strlen(term_env) > 0 ? term_env : server->conf->term, + strlen(term_env) > 0 ? term_env : server->conf->term, login_shell, "footclient", cwd, argc, argv, &term_shutdown_handler, client); if (client->term == NULL) { diff --git a/slave.c b/slave.c index 857640b2..3bff59b7 100644 --- a/slave.c +++ b/slave.c @@ -17,7 +17,7 @@ #include "tokenize.h" static void -slave_exec(int ptmx, char *const argv[], int err_fd) +slave_exec(int ptmx, char *argv[], int err_fd, bool login_shell) { int pts = -1; const char *pts_name = ptsname(ptmx); @@ -56,7 +56,20 @@ slave_exec(int ptmx, char *const argv[], int err_fd) close(pts); pts = -1; - execvp(argv[0], argv); + const char *file; + if (login_shell) { + file = strdup(argv[0]); + + char *arg0 = malloc(strlen(argv[0]) + 1 + 1); + arg0[0] = '-'; + arg0[1] = '\0'; + strcat(arg0, argv[0]); + + argv[0] = arg0; + } else + file = argv[0]; + + execvp(file, argv); err: (void)!write(err_fd, &errno, sizeof(errno)); @@ -70,7 +83,7 @@ err: pid_t slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv, - const char *term_env, const char *conf_shell) + const char *term_env, const char *conf_shell, bool login_shell) { int fork_pipe[2]; if (pipe2(fork_pipe, O_CLOEXEC) < 0) { @@ -107,7 +120,7 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv, setenv("TERM", term_env, 1); char **_shell_argv = NULL; - char *const *shell_argv = argv; + char **shell_argv = NULL; if (argc == 0) { char *shell_copy = strdup(conf_shell); @@ -117,9 +130,17 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv, _exit(0); } shell_argv = _shell_argv; + } else { + size_t count = 0; + for (; argv[count] != NULL; count++) + ; + shell_argv = malloc((count + 1) * sizeof(shell_argv[0])); + for (size_t i = 0; i < count; i++) + shell_argv[i] = argv[i]; + shell_argv[count] = NULL; } - slave_exec(ptmx, shell_argv, fork_pipe[1]); + slave_exec(ptmx, shell_argv, fork_pipe[1], login_shell); assert(false); break; diff --git a/slave.h b/slave.h index 63fe9bff..83891590 100644 --- a/slave.h +++ b/slave.h @@ -5,4 +5,4 @@ pid_t slave_spawn( int ptmx, int argc, const char *cwd, char *const *argv, const char *term_env, - const char *conf_shell); + const char *conf_shell, bool login_shell); diff --git a/terminal.c b/terminal.c index 89c18c75..37b2cc84 100644 --- a/terminal.c +++ b/terminal.c @@ -589,8 +589,8 @@ load_fonts_from_conf(const struct terminal *term, const struct config *conf, struct terminal * term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, - const char *term_env, const char *foot_exe, const char *cwd, - int argc, char *const *argv, + const char *term_env, bool login_shell, const char *foot_exe, + const char *cwd, int argc, char *const *argv, void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data) { int ptmx = -1; @@ -777,7 +777,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, term_font_dpi_changed(term); /* Start the slave/client */ - if ((term->slave = slave_spawn(term->ptmx, argc, term->cwd, argv, term_env, conf->shell)) == -1) + if ((term->slave = slave_spawn(term->ptmx, argc, term->cwd, argv, term_env, conf->shell, login_shell)) == -1) goto err; if (term->width == 0 && term->height == 0) { diff --git a/terminal.h b/terminal.h index d400dca5..d9727b32 100644 --- a/terminal.h +++ b/terminal.h @@ -356,8 +356,8 @@ struct terminal { struct config; struct terminal *term_init( const struct config *conf, struct fdm *fdm, struct wayland *wayl, - const char *term_env, const char *foot_exe, const char *cwd, - int argc, char *const *argv, + const char *term_env, bool login_shell, const char *foot_exe, + const char *cwd, int argc, char *const *argv, void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data); bool term_shutdown(struct terminal *term);