who命令

一、who命令

who命令用于查看当前系统中已经登陆过的用户信息

chanxiaoxi@ubuntu:~$ who
chanxiaoxi tty7         2013-06-01 09:38 (:0)
chanxiaoxi pts/1        2013-06-01 10:09 (:0)
chanxiaoxi pts/2        2013-06-01 10:12 (:0)
chanxiaoxi pts/3        2013-06-01 11:14 (:0)
chanxiaoxi pts/4        2013-06-01 11:22 (:0)

二、who命令的实现原理

通过查看联机手册可以知道,who命令的实现原理是,通过查找记录登陆信息的文件来获取系统中登陆过用户的信息。一般,系统将该文件存放在 /var/adm/utmp 或/var/run/utmp

这些可以通过查看手册可知

/* Compatibility names for the strings of the canonical file names.  */
#define UTMP_FILE	_PATH_UTMP
#define UTMP_FILENAME	_PATH_UTMP
#define WTMP_FILE	_PATH_WTMP
#define WTMP_FILENAME	_PATH_WTMP

chanxiaoxi@ubuntu:~$ more /usr/include/paths.h | grep _PATH_UTMP
#define	_PATH_UTMP	"/var/run/utmp"

但是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(8) */
               /* 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 (getsid(2)),
                                                used for windowing */
               struct {
                   int32_t tv_sec;           /* Seconds */
                   int32_t tv_usec;          /* Microseconds */
               } ut_tv;                      /* Time entry was made */
           #else
                long   ut_session;           /* Session ID */
                struct timeval ut_tv;        /* Time entry was made */
           #endif

               int32_t ut_addr_v6[4];        /* Internet address of remote
                                                host; IPv4 address uses
                                                just ut_addr_v6[0] */
               char __unused[20];            /* Reserved for future use */
           };

三、自己编写一个who命令

1、open、read、close

根据who命令的原理,我们的程序要能够打开存放登录记录的文件,然后还要能从中读取信息,最后关闭它并获得这些信息。

open

       Given a pathname for a file, open() returns a file descriptor, a small,
       nonnegative integer  for  use  in  subsequent  system  calls  (read(2),
       write(2), lseek(2), fcntl(2), etc.).  The file descriptor returned by a
       successful call will be the lowest-numbered file  descriptor  not  cur‐
       rently open for the process.

       int fd=open(char * filename,int how)

这个系统调用会在进程和文件之间建立一条链接,该链接用descriptor来标志。如果打开成功,会返回一个nonnegative integer(descriptor),如果打开失败,会返回-1

打开文件时必须指定文件名和打开方式,打开方式有三种:O_RDONLY、O_WRONLY、O_RDWR

read

       read()  attempts to read up to count bytes from file descriptor fd into
       the buffer starting at buf.
       If count is zero, read() returns zero and has  no  other  results.   If
       count is greater than SSIZE_MAX, the result is unspecified.

       ssize_t numread=read(int fd,void * buf,size_t qty)

       请求用户从fd所指定的文件中读取qty字节的数据并存放在buf中,读取成功则返回读取的字数,否则返回-1

close

       close()  closes  a  file descriptor, so that it no longer refers to any
       file and may be reused.  Any record locks (see fcntl(2))  held  on  the
       file  it  was  associated  with,  and owned by the process, are removed
       (regardless of the file descriptor that was used to obtain the lock).

       int result=close(int fd)

       若错误,返回-1


2、代码实现

/* who1.c - a first version of the who program
*  open,read UTMP file,and show results
*/
#include<stdio.h>
#include<stdlib.h>
#include<utmp.h>
#include<fcntl.h>
#include<unistd.h>

#define SHOWHOST

int main(){
	struct utmp current_record;
	int utmpfd;						/*read from this descriptor*/
	int reclen=sizeof(current_record);
	
	if((utmpfd=open(UTMP_FILE,O_RDONLY))==-1){  /*if failed return -1 */
		perror(UTMP_FILE);   /*print out error message */     
		exit(1);
	}

	while(read(utmpfd,¤t_record,reclen)==reclen) {
		show_info(¤t_record);
	}
	close(utmpfd);
	return 0;
}

/*
*show_info()
*displays contents of the utmp struct in human readable form
*note these sizes should not be hardwired
*/
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");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值