Allow dgamelaunch to kill processes that are idle for too long with SIGHUP. From Darshan Shaligram

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@530 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2010-03-02 18:02:51 +00:00
parent 6adfa1dca6
commit 9934d365bd
7 changed files with 35 additions and 4 deletions

View File

@ -82,6 +82,7 @@ cursor { return TYPE_CURSOR; }
"lockfile" { return TYPE_PATH_LOCKFILE; }
"inprogressdir" { return TYPE_PATH_INPROGRESS; }
"game_args" { return TYPE_GAME_ARGS; }
"max_idle_time" { return TYPE_MAX_IDLE_TIME; }
"rc_fmt" { return TYPE_RC_FMT; }
"ttyrecdir" { return TYPE_PATH_TTYREC; }
server_id { return TYPE_SERVER_ID; }

View File

@ -41,6 +41,7 @@ static const char* lookup_token (int t);
%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_TTYREC
%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
%token TYPE_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR
%token TYPE_MAX_IDLE_TIME
%token <s> TYPE_VALUE
%token <i> TYPE_NUMBER TYPE_CMDQUEUENAME
%type <kt> KeyType
@ -355,6 +356,10 @@ game_definition : TYPE_CMDQUEUE
{
/* nothing */
}
| TYPE_MAX_IDLE_TIME '=' TYPE_NUMBER
{
myconfig[ncnf]->max_idle_time = $3;
}
| KeyType '=' TYPE_VALUE
{
switch ( $1 ) {
@ -561,6 +566,7 @@ const char* lookup_token (int t)
case TYPE_PATH_TTYREC: return "ttyrecdir";
case TYPE_PATH_INPROGRESS: return "inprogressdir";
case TYPE_GAME_ARGS: return "game_args";
case TYPE_MAX_IDLE_TIME: return "max_idle_time";
case TYPE_RC_FMT: return "rc_fmt";
case TYPE_WATCH_SORTMODE: return "sortmode";
case TYPE_SERVER_ID: return "server_id";

View File

@ -101,6 +101,7 @@ struct dg_config
char **bin_args; /* args for game binary */
char *rc_fmt;
struct dg_cmdpart *cmdqueue;
int max_idle_time;
};
struct dg_globalconfig

View File

@ -45,7 +45,8 @@ struct dg_config defconfig = {
/* num_args = */ 0,
/* bin_args = */ NULL,
/* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
/* cmdqueue = */ NULL
/* cmdqueue = */ NULL,
/* max_idle_time = */ 0
};
char* config = NULL;

View File

@ -192,6 +192,10 @@ menu["watchmenu_help"] {
# # From inside the jail, the default .nethackrc that is copied for new users.
# # rc_template = "/dgl-default-rcfile"
#
# # If player idles longer than max_idle_time seconds, the game will
# # receive a sighup. Default value is 0, which disables the idling timer.
# max_idle_time = 2000
#
# # Make sure the inprogress dir actually exists. default is "inprogress/"
# # Each game you define here must have it's own.
# inprogressdir = "%rinprogress-nethackstub/"

View File

@ -71,6 +71,7 @@
#endif
int slave;
pid_t dgl_parent;
pid_t child, subchild;
pid_t input_child;
char* ipfile = NULL;
@ -89,6 +90,8 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
{
char dirname[100];
/* Note our PID to let children kill the main dgl process for idling */
dgl_parent = getpid();
child = subchild = input_child = 0;
if (!ttyrec_path) {
@ -140,7 +143,7 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
{
close (slave);
ipfile = gen_inprogress_lock (game, child, ttyrec_filename);
dooutput ();
dooutput (myconfig[game]->max_idle_time);
}
else
doshell (game, username);
@ -279,8 +282,17 @@ check_output (const char *str, int len)
}
}
void
dooutput ()
game_idle_kill(int signal)
{
kill(child, SIGHUP);
kill(dgl_parent, SIGHUP);
}
void
dooutput (int max_idle_time)
{
int cc;
time_t tvec, time ();
@ -289,6 +301,8 @@ dooutput ()
setbuf (stdout, NULL);
(void) close (0);
tvec = time ((time_t *) NULL);
/* Set up SIGALRM handler to kill idle games */
signal(SIGALRM, game_idle_kill);
for (;;)
{
Header h;
@ -296,6 +310,10 @@ dooutput ()
cc = read (master, obuf, BUFSIZ);
if (cc <= 0)
break;
if (max_idle_time)
alarm(max_idle_time);
if (uflg)
check_output (obuf, cc);
h.len = cc;

View File

@ -16,7 +16,7 @@ extern void fail (void);
extern void fixtty (void);
extern void getslave (void);
extern void doinput (void);
extern void dooutput (void);
extern void dooutput (int max_idle_time);
extern void doshell (int, char *);
extern void finish (int);
extern void remove_ipfile (void);