From 9934d365bd0ed3bd776674c0da2aa3bf6a070a3b Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 2 Mar 2010 18:02:51 +0000 Subject: [PATCH] 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 --- config.l | 1 + config.y | 6 ++++++ dgamelaunch.h | 1 + dgl-common.c | 3 ++- examples/dgamelaunch.conf | 4 ++++ ttyrec.c | 22 ++++++++++++++++++++-- ttyrec.h | 2 +- 7 files changed, 35 insertions(+), 4 deletions(-) diff --git a/config.l b/config.l index e94f252..17061af 100644 --- a/config.l +++ b/config.l @@ -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; } diff --git a/config.y b/config.y index 6694796..e10b990 100644 --- a/config.y +++ b/config.y @@ -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 TYPE_VALUE %token TYPE_NUMBER TYPE_CMDQUEUENAME %type 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"; diff --git a/dgamelaunch.h b/dgamelaunch.h index 7b3dc5f..636808e 100644 --- a/dgamelaunch.h +++ b/dgamelaunch.h @@ -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 diff --git a/dgl-common.c b/dgl-common.c index 67581e8..bd51108 100644 --- a/dgl-common.c +++ b/dgl-common.c @@ -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; diff --git a/examples/dgamelaunch.conf b/examples/dgamelaunch.conf index 868e644..827c645 100644 --- a/examples/dgamelaunch.conf +++ b/examples/dgamelaunch.conf @@ -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/" diff --git a/ttyrec.c b/ttyrec.c index 28af7e3..ea9f0d7 100644 --- a/ttyrec.c +++ b/ttyrec.c @@ -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; diff --git a/ttyrec.h b/ttyrec.h index 23d951a..34aa3c0 100644 --- a/ttyrec.h +++ b/ttyrec.h @@ -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);