who命令的基本实现(下)

在who命令的基本实现(上)这一篇博文介绍了who命令的基本原理,所以我们可以尝试着编写自己的who命令。

who1.c:

#include <stdio.h>
#include <stdlib.h>
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>

#define SHOWHOST	/* include remote machine on output */

void show_info (struct utmp*);

int main () {
	struct utmp current_record; /* read info into this variable */
	int utmpfd; /* just a file descriptor */
	int reclen = sizeof(current_record);
	
	if ((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1) {
		perror(UTMP_FILE); /* UTMP_FILE is in utmp.h */
		exit(1);
	}
	while (read(utmpfd, ¤t_record, reclen) == reclen) {
		show_info(¤t_record);
	}
	close(utmpfd);
	return 0;
}

void show_info (struct utmp* utbufp) {
	printf("%-8.8s", utbufp->ut_name);
	printf(" ");
	printf("%-8.8s", utbufp->ut_line);
	printf(" ");
	printf("%10ld", utbufp->ut_time);
	printf(" ");
#ifdef SHOWHOST
	printf("(%s)", utbufp->ut_host);
#endif
	printf("\n");
}

用以下命令将上述文件编译、运行:

cc who1.c -o who1
./who1 //在who1所在目录下运行这条命令

使用who1命令得到的结果为:

可以看到它能显示出:用户名、终端名、从登陆开始到目前为止的秒数、远程主机名。

我们的who1有两个不足:

无法正确的显示时间;

但与系统自带的who命令作对比可以发现:


系统中登陆的用户其实只有wzh这一个用户,这是因为utmp文件实际上包含所有终端的信息,包括那些尚未被用到的终端的信息也存放在utmp中。

who2.c:

1.

(使用man -k utmp命令可以看到以下两张图片的信息)


utmp结构体中有个ut_type属性。以下是ut_type可以有的一些值:


当ut_type的值为7时,表示这是一个已经登录的用户。因此,对程序作出修改:

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(" ");
	printf("%10ld", utbufp->ut_time);
	printf(" ");
#ifdef SHOWHOST
	printf("(%s)", utbufp->ut_host);
#endif
	printf("\n");
}
主要是添加上面代码片段中加粗的那条语句。
2.接下来修改显示登录时间的方式

who命令的基本实现(上)可以知道用户登录时间ut_time其实被定义为ut_tv结构体中的tv_sec变量,而tv_sec变量的类型为int32_t。

而我在utmp.h文件中是没发现int32_t的实际类型是什么:


但是我在utmp.h文件中发现它include了一个头文件。我猜想int32_t的实际类型可能会在这个头文件中定义。进一步查看可以知道int32_t的实际类型为int类型


使用如下命令查看关于时间的联机帮助:

man -k time

更好的过滤方法是:

man -k time | grep transform

man -k time | grep -i convert

这里使用的是ctime(3)来将表示时间的整数值转换成人们日常所使用的时间形式。

通过man 3 ctime命令查看可以发现下面这两段信息:



其中这篇博文介绍了追踪time_t实际类型的方法,time_t实际类型为long int。

这就表示ctime这个函数可以将指向用户登录时间ut_time的指针作为参数,然后该函数返回一个上图中显示的字符串。




系统为32位ubuntu的int,long,long int的字节数:


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值