who命令的编写
2013-01-10 15:06
148 查看
一.who的功能:
查看当前哪些用户正在使用系统二.who的工作流程:
从 /var/run/utmp 文件中读取已登录用户的信息,然后输出(注意:我的操作环境是ubuntu11.10 ,有些地方与其他系统不同)
如在我的ubuntu11.10中utmp.h在 /usr/include
和 /usr/include/i386-linux-gnu/bits 中
三.内容详解
/usr/include中的/utmp.h有:#include <bits/utmp.h> /* Compatibility names for the strings of the canonical file names. */ #define UTMP_FILE _PATH_UTMP
在path.h中有:
#define _PATH_UTMP "/var/run/utmp"则 UTMP_FILE 就是文件路径/var/run/utmp
/usr/include/i386-linux-gnu/bits/utmp.h中包含信息:
#ifndef _UTMP_H # error "Never include <bits/utmp.h> directly; use <utmp.h> instead." #endif #include <paths.h> #include <sys/time.h> #include <sys/types.h> #include <bits/wordsize.h> #define UT_LINESIZE 32 #define UT_NAMESIZE 32 #define UT_HOSTSIZE 256 /* The structure describing an entry in the database of previous logins. */ struct lastlog { #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 int32_t ll_time; #else __time_t ll_time; #endif char ll_line[UT_LINESIZE]; char ll_host[UT_HOSTSIZE]; }; /* The structure describing the status of a terminated process. This type is used in `struct utmp' below. */ struct exit_status { short int e_termination; /* Process termination status. */ short int e_exit; /* Process exit status. */ }; /* The structure describing an entry in the user accounting database. */ struct 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. */ #if __WORDSIZE == 64 && defined __WORDSIZE_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. */ }; /* Backwards compatibility hacks. */ #define ut_name ut_user #ifndef _NO_UT_TIME /* We have a problem here: `ut_time' is also used otherwise. Define _NO_UT_TIME if the compiler complains. */ # define ut_time ut_tv.tv_sec #endif #define ut_xtime ut_tv.tv_sec #define ut_addr ut_addr_v6[0] /* Values for the `ut_type' field of a `struct utmp'. */ #define EMPTY 0 /* No valid user accounting information. */ #define RUN_LVL 1 /* The system's runlevel. */ #define BOOT_TIME 2 /* Time of system boot. */ #define NEW_TIME 3 /* Time after system clock changed. */ #define OLD_TIME 4 /* Time when system clock changed. */ #define INIT_PROCESS 5 /* Process spawned by the init process. */ #define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ #define USER_PROCESS 7 /* Normal process. */ #define DEAD_PROCESS 8 /* Terminated process. */ #define ACCOUNTING 9 /* Old Linux name for the EMPTY type. */ #define UT_UNKNOWN EMPTY /* Tell the user that we have a modern system with UT_HOST, UT_PID, UT_TYPE, UT_ID and UT_TV fields. */ #define _HAVE_UT_TYPE 1 #define _HAVE_UT_PID 1 #define _HAVE_UT_ID 1 #define _HAVE_UT_TV 1 #define _HAVE_UT_HOST 1
struct utmp结构保存登录信息
四.自己写的who命令的代码(版本一):
#include<stdio.h> #include<utmp.h> #include<fcntl.h> #include<unistd.h> #include<stdlib.h> #include<time.h> #define SHOWHOST void showtime(long); void show_info(struct utmp *utbufp); int main() { struct utmp utbuf; // read info into here int utmpfd; // read from this descriptor if( (utmpfd = open(UTMP_FILE,O_RDONLY)) == -1) { perror(UTMP_FILE); //UTMP_FILE is in utmp.h exit(1); } while( read( utmpfd,&utbuf,sizeof(utbuf)) ==sizeof(utbuf)) show_info(&utbuf); close(utmpfd); return 0; } void show_info(struct utmp *utbufp) { if(utbufp->ut_type != USER_PROCESS) //ut_type==USER_PROCESS时,表示已经登录的用户 return ; printf("%-8.8s",utbufp->ut_user); printf(" "); printf("%-8.8s",utbufp->ut_line); printf(" "); showtime( utbufp->ut_time); // printf("%12.12s",ctime(&(utbufp->ut_tv).tv_sec)+4); printf(" "); #ifdef SHOWHOST if(utbufp->ut_host[0] != '\0') printf("(%s)",utbufp->ut_host); #endif printf("\n"); } void showtime(long timeval) { char *cp; cp = ctime(&timeval); printf("%12.12s",cp + 4); }
五.运用缓冲技术的who命令代码(版本二):
在版本一中,每次只能读取一个数据,因此需要不停的读取,所以导致效率低下。可以加入缓冲机制提高程序的运行效率。缓冲技术的主要思想是一次读入大量的数据放入缓冲区,需要的时候从缓冲区取得数据。程序使用一个 utmplib.c文件实现缓冲算法,在main函数中只要调用 utmplib.c中相应函数即可。在 utmplib.c中用一个能容纳16个utmp结构的数组作为缓冲区。utmp_next 函数来从缓冲区取得下一个utmp结构的数据。
修改原来的main 函数,通过调用utmp_next 来取得数据,当缓冲区的数据都被取出后,utmp_next会调用read,通过内核再次获得16条记录充满缓冲区,用这种方法可以是read的调用次数减少到原来的 1/16 。
utmplib.c 代码如下:
#include<stdio.h> #include<utmp.h> #include<fcntl.h> #include<sys/types.h> #define NRECS 16 #define NULLUT ((struct utmp *) NULL ) #define UTSIZE (sizeof(struct utmp)) static char utmpbuf[NRECS * UTSIZE]; //一次可以存储16个utmp结构的数组 static int num_recs; //缓冲区中的数据个数 static int cur_rec ; //缓冲区中已使用的数据个数 static int fd_utmp = -1; int utmp_open(char * filename) { fd_utmp = open(filename,O_RDONLY); cur_rec = num_recs = 0; return fd_utmp; } /* * utmp_reload返回值是缓冲区的数据个数 */ int utmp_reload() { int amt_read; amt_read = read(fd_utmp,utmpbuf,NRECS * UTSIZE); num_recs = amt_read/UTSIZE ; cur_rec = 0; return num_recs ; } /* * utmp_next 返回指向结构的指针 */ struct utmp *utmp_next() { struct utmp *recp; if( fd_utmp == -1) return NULLUT; if( cur_rec == num_recs && utmp_reload() == 0) return NULLUT; // recp指向下一个数据 recp = (struct utmp *)&utmpbuf[cur_rec * UTSIZE]; cur_rec++; return recp; } void utmp_close() { if(fd_utmp != -1) close(fd_utmp); }
who.c中只更改main函数,其余不变,main函数代码如下:
int main() { struct utmp *utbufp, *utmp_next(); if( (utmp_open(UTMP_FILE)) == -1) { perror(UTMP_FILE); //UTMP_FILE is in utmp.h exit(1); } while(( utbufp = utmp_next()) != ((struct utmp *) NULL)) show_info(utbufp); utmp_close(); return 0; }
相关文章推荐
- Linux下 使用C语言编写who命令
- 【Unix/Linux编程实践】从零做起:编写who命令
- 自己动手编写一个简单的who命令(不带参数)
- Linux下编写Who命令
- 自己动手编写一个简单的who命令(不带参数)
- 编写who命令--从Linux中学习Linux
- 编写自己的who命令
- 第2章 用户、文件操作与联机帮助:编写who命令
- 自己编写who命令
- 编写who命令:文件操作,缓冲区与联机帮助
- Shell命令编写——查看当前用户who
- Linux_自己编写一个who命令
- who命令的编写——登录与注销__who, whoami, who am i
- 编写who命令
- 《unix/linux编程实践教程》学习笔记:第二章 编写who,cp命令
- 第2章 用户、文件操作与联机帮助:编写who命令
- who 命令编写
- 编写who命令
- Linux下 使用C语言编写who命令
- 自己用C语言编写who命令