Add support for opening an existing PTY

Virtual machine monitor programs (e.g. QEMU, Cloud Hypervisor) expose
guest consoles as PTYs.  With this patch, foot can access these guest
consoles.

Usually, the program used for accessing these PTYs is screen, but
screen is barely developed, doesn't support resizing, and has a bunch
of other unrelated stuff going on.  It would be nice to have a
terminal emulator that properly supported opening an existing PTY.
The VMM controls the master end of the PTY, so to the other end (in
this case foot), it just behaves like any application running in a
directly-opened PTY, and all that's needed is to change foot's code to
support opening an existing PTY rather than creating one.

Co-authored-by: tanto <tanto@ccc.ac>
This commit is contained in:
Alyssa Ross 2021-12-10 17:40:59 +00:00 committed by Daniel Eklöf
parent 712bc95db3
commit 86894a1cd2
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
9 changed files with 76 additions and 32 deletions

19
main.c
View file

@ -3,6 +3,7 @@
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <limits.h>
#include <locale.h>
#include <getopt.h>
#include <signal.h>
@ -77,6 +78,7 @@ print_usage(const char *prog_name)
" -m,--maximized start in maximized mode\n"
" -F,--fullscreen start in fullscreen mode\n"
" -L,--login-shell start shell as a login shell\n"
" --pty=PATH display an existing PTY instead of creating one\n"
" -D,--working-directory=DIR directory to start in (CWD)\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
@ -172,6 +174,10 @@ sanitize_signals(void)
sigaction(i, &dfl, NULL);
}
enum {
PTY_OPTION = CHAR_MAX + 1,
};
int
main(int argc, char *const *argv)
{
@ -209,6 +215,7 @@ main(int argc, char *const *argv)
{"maximized", no_argument, NULL, 'm'},
{"fullscreen", no_argument, NULL, 'F'},
{"presentation-timings", no_argument, NULL, 'P'}, /* Undocumented */
{"pty", required_argument, NULL, PTY_OPTION},
{"print-pid", required_argument, NULL, 'p'},
{"log-level", required_argument, NULL, 'd'},
{"log-colorize", optional_argument, NULL, 'l'},
@ -221,6 +228,7 @@ main(int argc, char *const *argv)
bool check_config = false;
const char *conf_path = NULL;
const char *custom_cwd = NULL;
const char *pty_path = NULL;
bool as_server = false;
const char *conf_server_socket_path = NULL;
bool presentation_timings = false;
@ -316,6 +324,10 @@ main(int argc, char *const *argv)
conf_server_socket_path = optarg;
break;
case PTY_OPTION:
pty_path = optarg;
break;
case 'P':
presentation_timings = true;
break;
@ -383,6 +395,11 @@ main(int argc, char *const *argv)
}
}
if (as_server && pty_path) {
fputs("error: --pty is incompatible with server mode\n", stderr);
return ret;
}
log_init(log_colorize, as_server && log_syslog,
as_server ? LOG_FACILITY_DAEMON : LOG_FACILITY_USER, log_level);
@ -574,7 +591,7 @@ main(int argc, char *const *argv)
goto out;
if (!as_server && (term = term_init(
&conf, fdm, reaper, wayl, "foot", cwd, token,
&conf, fdm, reaper, wayl, "foot", cwd, token, pty_path,
argc, argv, NULL,
&term_shutdown_cb, &shutdown_ctx)) == NULL) {
goto out;