[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: Determine time of last keystroke and mouse movement



Tony Breeds wrote:
On Wed, May 13, 2009 at 02:49:38PM -0600, Orion Poplawski wrote:
Is there anyway for periodic (cron like) job running as root on Fedora 10 (and up) to determine time of the last keypress and mouse movement? Back in the day I could look at the access time of /dev/tty7, but this appears to be no longer the case (even when moving to /dev/tty1 to account for the vt1 X shift). Any ideas on how to determine this would be greatly appreciated.

I'm sure you can write something to read (and log) /dev/input/*  This daemon
could be started at system boot and /shouldn't/ interfere with system opperation.

Yours Tony


Thanks, this is the approach I've taken.  Yet Another Daemon.  <sigh>

--
Orion Poplawski
Technical Manager                     303-415-9701 x222
NWRA/CoRA Division                    FAX: 303-415-9702
3380 Mitchell Lane                  orion cora nwra com
Boulder, CO 80301              http://www.cora.nwra.com
/*
 * inputwatch - 
 *
 * inputwatch monitors all of the eventX entries in /dev/input and updates
 * the timestamp of the file /var/spool/input when input is detected.
 *
 * Copyright 2009 Orion Poplawski
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#define _SVID_SOURCE
/* For futimens */
#define _GNU_SOURCE
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/select.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>

#undef max
#define max(x,y) ((x) > (y) ? (x) : (y))

/* We only want the eventX entries in /dev/input */
int evmatch(const struct dirent *entry) {
    return (strncmp("event",entry->d_name,5) == 0);
}

int main(void)
{
    struct dirent **inputs;
    /* Find all of the eventX entries in /dev/input */
    int numfds = scandir("/dev/input", &inputs, evmatch, 0);
    if (numfds < 0) {
       perror("Cannot scan /dev/input");
       exit(1);
    }

    close(0);
    close(1);
    close(2);

    fd_set rfds;
    FD_ZERO(&rfds);
    int nfds = 0, inputfd[__FD_SETSIZE], i;
    char inputname[__FD_SETSIZE][FILENAME_MAX];
    /* Open all of the event files and add them to our select list */
    for (i=0; i<numfds; i++) {
       sprintf(inputname[i],"/dev/input/%s",inputs[i]->d_name);
       inputfd[i] = open(inputname[i], O_RDONLY);
       nfds = max(nfds, inputfd[i]);
       FD_SET(inputfd[i], &rfds);
    }
    nfds++;

    pid_t pid = fork();

    if (pid == 0) {
        /* Open our status file */
        int evfd = open("/var/spool/input", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666);
        for (;;) {
            /* Reload file descriptors to watch */
            fd_set srfds = rfds;

            /* Wait for input */
            int retval = select(nfds, &srfds, NULL, NULL, NULL);

            if (retval > 0) {
                /* Drain all input */
                for (i=0; i<numfds; i++) {
                    if (FD_ISSET(inputfd[i],&srfds)) {
                       char buf[2048];
                       while (read(inputfd[i], buf, 2048) == 2048) {}
                    }
                }

                /* Update the status file */
                futimens(evfd, NULL);
                struct timespec req, rem;

                /* Sleep - we don't need high time resolution on status file */
                req.tv_sec = 10;
                req.tv_nsec = 0;
                nanosleep(&req, &rem);
            }
        }
    }
    exit(0);
}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]