Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 52 additions & 32 deletions src/unix/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,48 +204,68 @@ static void term_handler(int signum)
terminate_flag = signum;
}

/*
=================
Sys_SetSignalHandler

Configures a signal handler using sigaction.
Returns true on success.
=================
*/
static bool Sys_SetSignalHandler(int signum, void (*handler)(int), int flags)
{
struct sigaction sa;

sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
sa.sa_flags = flags;

return sigaction(signum, &sa, NULL) == 0;
}

/*
=================
Sys_Init
=================
*/
void Sys_Init(void)
{
const char *homedir;

signal(SIGTERM, term_handler);
signal(SIGINT, term_handler);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, term_handler);
signal(SIGUSR1, usr1_handler);

// basedir <path>
// allows the game to run from outside the data tree
sys_basedir = Cvar_Get("basedir", DATADIR, CVAR_NOSET);

// homedir <path>
// specifies per-user writable directory for demos, screenshots, etc
if (HOMEDIR[0] == '~') {
char *s = getenv("HOME");
if (s && strlen(s) >= MAX_OSPATH - MAX_QPATH)
Sys_Error("HOME path too long");
if (s && *s) {
homedir = va("%s%s", s, &HOMEDIR[1]);
} else {
homedir = "";
}
} else {
homedir = HOMEDIR;
}
const char *homedir;

if (!Sys_SetSignalHandler(SIGTERM, term_handler, 0) ||
!Sys_SetSignalHandler(SIGINT, term_handler, 0) ||
!Sys_SetSignalHandler(SIGTTIN, SIG_IGN, 0) ||
!Sys_SetSignalHandler(SIGTTOU, SIG_IGN, 0) ||
!Sys_SetSignalHandler(SIGPIPE, SIG_IGN, 0) ||
!Sys_SetSignalHandler(SIGHUP, term_handler, 0) ||
!Sys_SetSignalHandler(SIGUSR1, usr1_handler, SA_RESTART)) {
Sys_Error("Failed to install signal handlers");
}

sys_homedir = Cvar_Get("homedir", homedir, CVAR_NOSET);
sys_libdir = Cvar_Get("libdir", LIBDIR, CVAR_NOSET);
// basedir <path>
// allows the game to run from outside the data tree
sys_basedir = Cvar_Get("basedir", DATADIR, CVAR_NOSET);

// homedir <path>
// specifies per-user writable directory for demos, screenshots, etc
if (HOMEDIR[0] == '~') {
char *s = getenv("HOME");
if (s && strlen(s) >= MAX_OSPATH - MAX_QPATH)
Sys_Error("HOME path too long");
if (s && *s) {
homedir = va("%s%s", s, &HOMEDIR[1]);
} else {
homedir = "";
}
} else {
homedir = HOMEDIR;
}

tty_init_input();
}
sys_homedir = Cvar_Get("homedir", homedir, CVAR_NOSET);
sys_libdir = Cvar_Get("libdir", LIBDIR, CVAR_NOSET);

tty_init_input();
}
/*
=================
Sys_Error
Expand Down
19 changes: 17 additions & 2 deletions src/unix/tty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,18 @@ static void tty_parse_input(const char *text)
}
}

/*
=============
winch_handler

Forces a refresh of the visible input line on terminal resize.
=============
*/
#ifdef TIOCGWINSZ
static void winch_handler(int signum)
{
tty_prompt.inputLine.visibleChars = 0; // force refresh
(void)signum;
tty_prompt.inputLine.visibleChars = 0; // force refresh
}
#endif

Expand Down Expand Up @@ -567,7 +575,14 @@ void tty_init_input(void)
goto no_tty;

#ifdef TIOCGWINSZ
signal(SIGWINCH, winch_handler);
struct sigaction sa;

sigemptyset(&sa.sa_mask);
sa.sa_handler = winch_handler;
sa.sa_flags = SA_RESTART;

if (sigaction(SIGWINCH, &sa, NULL) != 0)
goto no_tty;
#endif

// determine terminal width
Expand Down