编写linux命令之who

linux中经常用到who命令查看登录信息如:

$ who
v        tty1         Feb 18 16:33 (:0)
v        pts/0        Feb 18 16:33 (:0)
v        pts/1        Feb 18 16:33 (:0)

那么如何写一个who命令程序呢

先上代码

#include<stdio.h>
#include<stdlib.h>
#include<utmp.h>
#include<fcntl.h>//open()
#include<unistd.h>//read(),close()
#include<time.h>
#define SHOWHOST
int show_info(struct utmp *utbufp);
void showTime(long timeval);
int main()
{
    struct utmp current_record;//实例化的对象 将要把读出的数据存在这
    int utmpfd;//文件描述符
    int reclen=sizeof(current_record);
    if((utmpfd=open(UTMP_FILE,O_RDONLY))==-1)//UTMP_FILE是utmp.h中的宏定义
    {
        perror(UTMP_FILE);
        exit(1);
    }
    while(read(utmpfd,&current_record,reclen)==reclen)//循环打印,确保所有用户都列出
    {
        show_info(&current_record);
    }
    close(utmpfd);
    return 0;
}
void showTime(long timeval)
{
    char *cp=ctime(&timeval);
    printf("%12.16s",cp );
}
int show_info(struct utmp *utbufp)
{
    if(utbufp->ut_type!=USER_PROCESS)//确保是一个登录的用户,utmp.h中定义了USER_PROCESS当它的值是7时,说明是一个登录用户
    {
        return 0;
    }
    printf("% -8.8s",utbufp->ut_name);
    printf(" ");
    printf("% -8.8s",utbufp->ut_line);
    printf(" ");
    showTime(utbufp->ut_time);
    printf(" ");
#ifdef SHOWHOST
    if(utbufp->ut_host[0]!='\0')
        printf("(%s)",utbufp->ut_host);
#endif
    printf("\n");
    return 0;
}

需要首先说明在linux中头文件utmp.h定义了系统的用户登录记录,通过man帮助(man 5 utmp)可以查到在这个头文件中定义了结构体utmp:

//这里只显示其中一部分
struct utmp {
               short   ut_type;              /* Type of record */
               pid_t   ut_pid;               /* PID of login process */
               char    ut_line[UT_LINESIZE]; /* Device name of tty - "/dev/" */
               char    ut_id[4];             /* Terminal name suffix,
                                                or inittab(5) ID */
               char    ut_user[UT_NAMESIZE]; /* Username */
               char    ut_host[UT_HOSTSIZE]; /* Hostname for remote login, or
                                                kernel version for run-level
                                                messages */
               struct  exit_status ut_exit;  /* Exit status of a process
                                                marked as DEAD_PROCESS; not
                                                used by Linux init (1 */

通过其中的注释可以看到ut_line储存tty,另外在该结构中还定义了登录用户ut_name,登录时间点ut_time,所以我们只需实例化一个utmp对象,将所要用到的数据导入这个对象的成员中,再打印在终端上即可。

那么如何读取我们所需要的数据呢,可以用open()函数打开存储相关信息的文件,read()函数读出该文件中的内容并将数据写入已经实例化的utmp实体,以上两个函数分别在头文件fcntl.h和unistd.h中被定义。
至此源代码的大致思路已经完成,具体实现见上

对源代码中一些地方的说明:

1

UTMP_FILE在utmp.h中被定义:

#define UTMP_FILE	_PATH_UTMP

而_PATH_UTMP在/usr/include/paths.h中被定义

#define _PATH_UTMP      "/var/run/utmp"

所以说UTMP_FILE即为/var/run/utmp 此文件不是文本文件

2

在源代码中使用了ctime()是因为utbufp->ut_time的值是距离1970.1.1的秒数总和,是长整形,要把其转换为易读的时间格式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值