/* who_test.c */ #include<stdio.h> #include<string.h> #include<getopt.h> #include<time.h> #include<stdlib.h> #include<stdbool.h> #include<utmp.h> //设置标志位,用来标志命令行参数 bool opt_H = false; bool opt_q = false; /**mywho函数是调用系统数据文件的核心程序; ***它首先调用系统数据文件的接口函数,然后逐条将其数据保存下来; ***根据选项的标记为,然后输出不同的信息 ***关闭系统数据文件 ***/ static int mywho() { /* *在系统的数据文件中,提供两个文件 utmp 和 wtmp 两个文件 * 这两个文件记录的数据结构就是utmp, 所以要声明一个utmp数据结构 */ struct utmp *um; char timebuf[24]; int users = 0; //当命令选型为 -q, 用来保存用户数量 if (opt_q) { /** getutent 函数用来读下一条记录,如果需要,还会打开该文件。 *返回一个指向 utmp 的指针。 */ while ((um == getutent())) { if (um->ut_type != USER_PROCESS) /* 利用 utmp 结构的ut_type域,过滤出普通进程 */ { continue; } printf("%-2s ", um->ut_user); users += 1; } printf(" # users = %d ", users); endutent(); return 0; } //打印各栏标题头部 if (opt_H) { printf("%-12s%-12s%-20.20s %s ","NAME", "LINE", "TIME", "COMMENT"); } //此处处理的是 utmp 文件的内容 while ((um = getutent())) { // 利用 utmp 结构的ut_type域,过滤出普通进程 if (um->ut_type != USER_PROCESS) { continue; } time_t tm; tm = (time_t)(um->ut_tv.tv_sec); strftime(timebuf, 24, "%F %R", localtime(&tm)); printf("%-12s%-12s%-20.20s (%s) ", um->ut_user, um->ut_line, timebuf, um->ut_host); } endutent(); return 0; } int main(int argc, char **argv) { int c; int ok; while ((c = getopt(argc, argv, "Hqb")) != -1) { switch(c) { case 'H': opt_H = true; break; case 'q': opt_q = true; break; default: exit(1); } } if (argc != optind) { printf("fault command! "); } ok = mywho(); if (!ok) { return 0; } else { exit(1); } }
运行结果: