who命令用于显示当前系统中已经登录的用户信息,用户登录信息存储在utmp文件中,utmp.h在/usr/include/bits/下,utmp文件的结构如下:
{
short int ut_type; /* Type of login. */
pid_t ut_pid; /* Process ID of login process. */
char ut_line[UT_LINESIZE]; /* Devicename. */
char ut_id[4]; /* Inittab ID. */
char ut_user[UT_NAMESIZE]; /* Username. */
char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */
struct exit_status ut_exit; /* Exit status of a process marked
as DEAD_PROCESS. */
/* The ut_session and ut_tv fields must be the same size when compiled
32- and 64-bit. This allows data files and shared memory to be
shared between 32- and 64-bit applications. */
#ifdef __WORDSIZE_TIME64_COMPAT32
int32_t ut_session; /* Session ID, used for windowing. */
struct
{
int32_t tv_sec; /* Seconds. */
int32_t tv_usec; /* Microseconds. */
} ut_tv; /* Time entry was made. */
#else
long int ut_session; /* Session ID, used for windowing. */
struct timeval ut_tv; /* Time entry was made. */
#endif
int32_t ut_addr_v6[4]; /* Internet address of remote host. */
char __unused[20]; /* Reserved for future use. */
};
who的实现如下:who1.c
#include <unistd.h>
#include <utmp.h>
#include <fcntl.h>
#include <time.h>
void showtime(long);
void show_info(struct utmp *);
int main()
{
struct utmp utbuf;
int utmpfd;
if ((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1){
perror(UTMP_FILE);
exit(1);
}
while (read(utmpfd, &utbuf, sizeof(utbuf)) == sizeof(utbuf))
show_info(&utbuf);
close(utmpfd);
return 0;
}
void showtime(long timeval)
{
char *cp;
cp = ctime(&timeval);
printf("%12.12s", cp+4);
}
void show_info(struct utmp *utbufp)
{
if (utbufp->ut_type != USER_PROCESS)
return;
printf("% - 8.8s", utbufp->ut_name);
printf(" ");
printf("% - 8.8s", utbufp->ut_line);
printf(" ");
showtime(utbufp->ut_time);
printf(" ");
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host);
#endif
printf("\n");
}
编译:
gcc who1.c -o who1
运行:
who1
结果:
root pts/1 Nov 19 20:19
root pts/3 Nov 19 21:38
参考文献:
<<Linux/Unix编程实践教程>>