How does the `w` command know the idle time and the running command

w

The w command shows a bunch of information about who's logged in what they are doing.

Example from Wikipedia:

$ w
 11:12am up 608 day(s), 19:56,  6 users,  load average: 0.36, 0.36, 0.37
User     tty       login@  idle  what
smithj   pts/5      8:52am       w
jonesm   pts/23    20Apr06    28 -bash
harry    pts/18     9:01am     9 pine
peterb   pts/19    21Apr06       emacs -nw html/index.html
janetmcq pts/8     10:12am 3days -csh
singh    pts/12    16Apr06  5:29 /usr/bin/perl -w perl/test/program.pl

I know that it gets the first 3 columns' information from utmp and wtmp, which has read permissions for everyone, but where does it get the information for idle time and what the user is currently doing?

ls -l $(which w) shows that the w program does not have the setuid bit set and as a regular user, I have no permission to see other processes in /proc.

Best Answer

On linux at least, since any user input on the terminal will access the current user device it does a stat() call to /dev/{tty,pts/}?* and checks for atime for logged in users.

From w.c:

    /* stat the device file to get an idle time */
    static time_t idletime(const char *restrict const tty)
    {
            struct stat sbuf;
            if (stat(tty, &sbuf) != 0)
                    return 0;
            return time(NULL) - sbuf.st_atime;
    }

    static void showinfo(utmp_t * u, int formtype, int maxcmd, int from,
    ...
            print_time_ival7(idletime(tty), 0, stdout);
    ...

stat() only requires execute (x) permissions on parent directory to work.

Related Question