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
72 changes: 55 additions & 17 deletions src/unix/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>

#if USE_MEMORY_TRACES && HAVE_BACKTRACE
#include <execinfo.h>
Expand Down Expand Up @@ -151,24 +152,61 @@ bool Sys_GetAntiCheatAPI(void)
}
#endif

/*
=============
Sys_SetNonBlock

Set or clear non-blocking flag for the given descriptor.
=============
*/
bool Sys_SetNonBlock(int fd, bool nb)
{
int ret = fcntl(fd, F_GETFL, 0);
if (ret == -1)
return false;
if ((bool)(ret & O_NONBLOCK) == nb)
return true;
return fcntl(fd, F_SETFL, ret ^ O_NONBLOCK) == 0;
int ret = fcntl(fd, F_GETFL, 0);
if (ret == -1)
return false;
if ((bool)(ret & O_NONBLOCK) == nb)
return true;
return fcntl(fd, F_SETFL, ret ^ O_NONBLOCK) == 0;
}

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

Install a signal handler with given flags and mask.
=============
*/
static void Sys_SetSignalHandler(int signum, void (*handler)(int), int flags)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
sa.sa_flags = flags;

if (sigaction(signum, &sa, NULL) == -1)
Sys_Error("Failed to install handler for signal %d: %s", signum, strerror(errno));
}

/*
=============
usr1_handler
=============
*/
static void usr1_handler(int signum)
{
flush_logs = true;
flush_logs = true;
}

/*
=============
term_handler
=============
*/
static void term_handler(int signum)
{
terminate = signum;
terminate = signum;
}

/*
Expand All @@ -178,15 +216,15 @@ 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);
const char *homedir;

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, SA_RESTART);
Sys_SetSignalHandler(SIGUSR1, usr1_handler, SA_RESTART);

// basedir <path>
// allows the game to run from outside the data tree
Expand Down
30 changes: 28 additions & 2 deletions src/unix/tty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <poll.h>

#include <array>
Expand Down Expand Up @@ -519,9 +520,33 @@ static void tty_parse_input(const char *text)
}

#ifdef TIOCGWINSZ
/*
=============
winch_handler
=============
*/
static void winch_handler(int signum)
{
tty_prompt.inputLine.visibleChars = 0; // force refresh
tty_prompt.inputLine.visibleChars = 0; // force refresh
}

/*
=============
tty_install_winch_handler

Install SIGWINCH handler with restart semantics for TTY refresh.
=============
*/
static bool tty_install_winch_handler(void)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = winch_handler;
sa.sa_flags = SA_RESTART;

return sigaction(SIGWINCH, &sa, NULL) == 0;
}
#endif

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

#ifdef TIOCGWINSZ
signal(SIGWINCH, winch_handler);
if (!tty_install_winch_handler())
goto no_tty;
#endif

// determine terminal width
Expand Down