Show idle time based on input rather than output

Place additional file in the inprogressdir, same format but with
'.in' appended. User input is written to this file, so its modify time
updates when the user is playing.
Next, calculate idle_time based on the '.in' file instead of the ttyrec.
Add some checks to the code handling lockfiles in inprogressdir, to
ignore '.in' files that should be there and unlink orphaned ones.

squashed commits:
move input tracking file to inprogressdir
remove inputrec file on game exit
remove stale .in files
This commit is contained in:
Joanna Doyle 2021-07-30 04:12:01 +02:00
parent 55bd7dce01
commit a259a93f80
No known key found for this signature in database
GPG Key ID: 3C392FB3FD1F5AB9
4 changed files with 61 additions and 11 deletions

View File

@ -2500,7 +2500,7 @@ purge_stale_locks (int game)
while ((dent = readdir (pdir)) != NULL)
{
FILE *ipfile;
char *colon, *fn;
char *colon, *fn, *fn_in;
char buf[16];
pid_t pid;
size_t len;
@ -2525,6 +2525,24 @@ purge_stale_locks (int game)
snprintf (fn, len, "%s%s", dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL), dent->d_name);
/* skip .in files */
if (len >= 3) {
char *tmp = fn + len - 4;
if (!strcmp(tmp, ".in")) {
fn[len-4] = '\0';
printf("%s", fn);
/* unlink .in file if it's orphaned */
if (stat(fn, NULL)) {
fn[len-4] = '.';
unlink(fn);
}
free(fn);
continue;
}
}
fn_in = malloc(len + 3);
snprintf (fn_in, len + 3, "%s.in", fn);
if (!(ipfile = fopen (fn, "r"))) {
debug_write("purge_stale_locks fopen inprogressdir fail");
graceful_exit (202);
@ -2608,6 +2626,8 @@ purge_stale_locks (int game)
/* Don't remove the lock file until the process is dead. */
unlink (fn);
free (fn);
unlink (fn_in);
free (fn_in);
}
closedir (pdir);

View File

@ -387,7 +387,8 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
idle_alarm_set_enabled(0);
/* launch program */
ttyrec_main (userchoice, me->username,
dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL),
strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL)),
strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->inprogressdir, NULL)),
gen_ttyrec_filename());
idle_alarm_set_enabled(1);
played = 1;
@ -612,7 +613,7 @@ populate_games (int xgame, int *l, struct dg_user *me)
DIR *pdir;
struct dirent *pdirent;
struct stat pstat;
char fullname[130], ttyrecname[130], pidws[80], playername[DGL_PLAYERNAMELEN+1];
char fullname[130], fullname_in[135], ttyrecname[130], pidws[80], playername[DGL_PLAYERNAMELEN+1];
char *replacestr, *dir, *p;
struct dg_game **games = NULL;
struct flock fl = { 0 };
@ -641,12 +642,17 @@ populate_games (int xgame, int *l, struct dg_user *me)
char *inprog = NULL;
if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
continue;
if (strlen(pdirent->d_name) >= 3) {
char *tmp = pdirent->d_name + strlen(pdirent->d_name) - 3;
if (!strcmp(tmp, ".in")) continue;
}
inprog = dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL);
if (!inprog) continue;
snprintf (fullname, 130, "%s%s", inprog, pdirent->d_name);
snprintf (fullname_in, 135, "%s.in", fullname);
fd = 0;
/* O_RDWR here should be O_RDONLY, but we need to test for
@ -671,7 +677,7 @@ populate_games (int xgame, int *l, struct dg_user *me)
if (!ttrecdir) continue;
snprintf (ttyrecname, 130, "%s%s", ttrecdir, replacestr);
if (!stat (ttyrecname, &pstat))
if (!stat (fullname_in, &pstat))
{
/* now it's a valid game for sure */
games = realloc (games, sizeof (struct dg_game) * (len + 1));

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* 1999-02-22 Arkadiusz Mikiewicz <misiek@misiek.eu.org>
/* 1999-02-22 Arkadiusz Miśkiewicz <misiek@misiek.eu.org>
* - added Native Language Support
*/
@ -78,10 +78,12 @@ pid_t dgl_parent;
pid_t child, subchild;
pid_t input_child;
char* ipfile = NULL;
char* inputrec_file = NULL;
volatile int wait_for_menu = 0;
FILE *fscript;
FILE *inputrec;
int master;
struct termios tt;
@ -132,9 +134,9 @@ ttyrec_id(int game, char *username, char *ttyrec_filename)
}
int
ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
ttyrec_main (int game, char *username, char *ttyrec_path, char *inprog_path, char* ttyrec_filename)
{
char dirname[100];
char dirname[100], inputrec_path[135];
/* Note our PID to let children kill the main dgl process for idling */
dgl_parent = getpid();
@ -163,7 +165,12 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
if (ancient_encoding == -1)
query_encoding(game, username);
if (inprog_path[strlen(inprog_path)-1] == '/')
snprintf (inputrec_path, 135, "%s%s:%s.in", inprog_path, username, ttyrec_filename);
else
snprintf (inputrec_path, 135, "%s/%s:%s.in", inprog_path, username, ttyrec_filename);
snprintf(last_ttyrec, 512, "%s", dirname);
inputrec_file = strdup(inputrec_path);
atexit(&remove_ipfile);
if ((fscript = fopen (dirname, "w")) == NULL)
@ -210,8 +217,18 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
perror ("fork2");
fail ();
}
if (!input_child)
doinput ();
if (!input_child) {
if ((inputrec = fopen (inputrec_path, "w")) == NULL)
{
perror (inputrec);
fail ();
}
setbuf (inputrec, NULL);
doinput ();
fclose(inputrec);
unlink(inputrec_path);
}
else
{
while (wait_for_menu)
@ -230,8 +247,10 @@ doinput ()
register int cc;
char ibuf[BUFSIZ];
while ((cc = read (0, ibuf, BUFSIZ)) > 0)
while ((cc = read (0, ibuf, BUFSIZ)) > 0) {
(void) write (master, ibuf, cc);
(void) fwrite (ibuf, 1, cc, inputrec);
}
done ();
}
@ -592,6 +611,11 @@ remove_ipfile (void)
free(ipfile);
ipfile = NULL;
}
if (inputrec_file) {
unlink(inputrec_file);
free(inputrec_file);
inputrec_file = NULL;
}
signal(SIGALRM, SIG_IGN);
}

View File

@ -21,7 +21,7 @@ extern void doshell (int, char *);
extern void finish (int);
extern void remove_ipfile (void);
extern int ttyrec_main (int, char *username, char *ttyrec_path, char* ttyrec_filename);
extern int ttyrec_main (int, char *username, char *ttyrec_path, char *inprog_path, char* ttyrec_filename);
extern pid_t child; /* nethack process */
extern int master, slave;