"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; }
%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
{
/* nothing */
}
+ | TYPE_MAX_IDLE_TIME '=' TYPE_NUMBER
+ {
+ myconfig[ncnf]->max_idle_time = $3;
+ }
| KeyType '=' TYPE_VALUE
{
switch ( $1 ) {
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";
char **bin_args; /* args for game binary */
char *rc_fmt;
struct dg_cmdpart *cmdqueue;
+ int max_idle_time;
};
struct dg_globalconfig
/* 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;
# # 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/"
#endif
int slave;
+pid_t dgl_parent;
pid_t child, subchild;
pid_t input_child;
char* ipfile = NULL;
{
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) {
{
close (slave);
ipfile = gen_inprogress_lock (game, child, ttyrec_filename);
- dooutput ();
+ dooutput (myconfig[game]->max_idle_time);
}
else
doshell (game, username);
}
}
+
+
+void
+game_idle_kill(int signal)
+{
+ kill(child, SIGHUP);
+ kill(dgl_parent, SIGHUP);
+}
+
void
-dooutput ()
+dooutput (int max_idle_time)
{
int cc;
time_t tvec, time ();
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;
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;
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);