wdye: read out the whole terminfo database
All checks were successful
Alpine 3.20 Success
OpenBSD 7.5 Success

Also update LICENSE years.
This commit is contained in:
Přemysl Eric Janouch 2025-01-06 11:57:17 +01:00
parent 5c02778ff8
commit 9fe576ae9e
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 51 additions and 11 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2014 - 2024, Přemysl Eric Janouch <p@janouch.name> Copyright (c) 2014 - 2025, Přemysl Eric Janouch <p@janouch.name>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted. purpose with or without fee is hereby granted.

View File

@ -608,7 +608,7 @@ process_feed (struct process *self)
{ {
if (errno == EINTR) if (errno == EINTR)
return true; return true;
#if __linux__ #ifdef __linux__
// https://unix.stackexchange.com/a/538271 // https://unix.stackexchange.com/a/538271
if (errno == EIO) if (errno == EIO)
return false; return false;
@ -637,25 +637,59 @@ static luaL_Reg xlua_process_table[] =
// --- Terminal ---------------------------------------------------------------- // --- Terminal ----------------------------------------------------------------
struct terminfo_entry
{
enum { TERMINFO_BOOLEAN, TERMINFO_NUMERIC, TERMINFO_STRING } kind;
unsigned numeric;
char string[];
};
#ifdef WITH_CURSES #ifdef WITH_CURSES
static bool static bool
load_terminfo (const char *term, struct str_map *strings) load_terminfo (const char *term, struct str_map *strings)
{ {
// TODO(p): See if we can get away with using a bogus FD. // Neither ncurses nor NetBSD curses need an actual terminal FD passed.
// We don't want them to read out the winsize, we just read the database.
int err = 0; int err = 0;
TERMINAL *saved_term = set_curterm (NULL); TERMINAL *saved_term = set_curterm (NULL);
if (setupterm ((char *) term, STDOUT_FILENO, &err) != OK) if (setupterm ((char *) term, -1, &err) != OK)
{ {
set_curterm (saved_term); set_curterm (saved_term);
return false; return false;
} }
for (size_t i = 0; boolfnames[i]; i++)
{
int flag = tigetflag (boolnames[i]);
if (flag <= 0)
continue;
struct terminfo_entry *entry = xcalloc (1, sizeof *entry + 1);
*entry = (struct terminfo_entry) { TERMINFO_BOOLEAN, true };
str_map_set (strings, boolfnames[i], entry);
}
for (size_t i = 0; numfnames[i]; i++)
{
int num = tigetnum (numnames[i]);
if (num < 0)
continue;
struct terminfo_entry *entry = xcalloc (1, sizeof *entry + 1);
*entry = (struct terminfo_entry) { TERMINFO_NUMERIC, num };
str_map_set (strings, numfnames[i], entry);
}
for (size_t i = 0; strfnames[i]; i++) for (size_t i = 0; strfnames[i]; i++)
{ {
const char *value = tigetstr (strnames[i]); const char *str = tigetstr (strnames[i]);
if (value && value != (char *) -1) if (!str || str == (const char *) -1)
str_map_set (strings, strfnames[i], xstrdup (value)); continue;
size_t len = strlen (str) + 1;
struct terminfo_entry *entry = xcalloc (1, sizeof *entry + len);
*entry = (struct terminfo_entry) { TERMINFO_STRING, 0 };
memcpy (entry + 1, str, len);
str_map_set (strings, strfnames[i], entry);
} }
del_curterm (set_curterm (saved_term)); del_curterm (set_curterm (saved_term));
return true; return true;
@ -668,7 +702,7 @@ load_terminfo (const char *term, struct str_map *strings)
struct spawn_context struct spawn_context
{ {
struct str_map env; ///< Subprocess environment map struct str_map env; ///< Subprocess environment map
struct str_map term; ///< terminfo database strings struct str_map term; ///< terminfo database
struct strv envv; ///< Subprocess environment vector struct strv envv; ///< Subprocess environment vector
struct strv argv; ///< Subprocess argument vector struct strv argv; ///< Subprocess argument vector
@ -789,11 +823,17 @@ spawn_protected (lua_State *L)
// This could be made into an object that can adjust winsize/termios. // This could be made into an object that can adjust winsize/termios.
lua_createtable (L, 0, ctx->term.len); lua_createtable (L, 0, ctx->term.len);
struct str_map_iter iter = str_map_iter_make (&ctx->term); struct str_map_iter iter = str_map_iter_make (&ctx->term);
const char *value = NULL; const struct terminfo_entry *entry = NULL;
while ((value = str_map_iter_next (&iter))) while ((entry = str_map_iter_next (&iter)))
{ {
lua_pushstring (L, iter.link->key); lua_pushstring (L, iter.link->key);
lua_pushstring (L, value); switch (entry->kind)
{
break; case TERMINFO_BOOLEAN: lua_pushboolean (L, true);
break; case TERMINFO_NUMERIC: lua_pushinteger (L, entry->numeric);
break; case TERMINFO_STRING: lua_pushstring (L, entry->string);
break; default: lua_pushnil (L);
}
lua_settable (L, -3); lua_settable (L, -3);
} }
process->ref_term = luaL_ref (L, LUA_REGISTRYINDEX); process->ref_term = luaL_ref (L, LUA_REGISTRYINDEX);