Idea: There is a file named Utmp in the UNIX system that contains information about the user currently logged in to the system. Utmp This file holds a structure array, and the array element is the structure of the utmp type. To implement the WHO command, simply read out the structure of the utmp type from the Utmp file and then display it in the appropriate way. If you read only one structure data from a file at a time, then each struct is called in turn. And because system calls are time consuming (involving user-to-kernel switching), this can result in inefficient programs. We use buffer technology, each time from the file to read a number of structural data into memory, when the data has been displayed in the terminal, we then read the data from the file, which can effectively improve the efficiency of the program.
Code:
Utmplib.c
#include <fcntl.h> #include <sys/types.h> #include <utmp.h> #define NRECS 16#define utsize (sizeof ( struct utmp)) #define UTNULL ((struct utmp *) NULL) static char utmp_buffer[nrecs * utsize];static int utmp_num;static int CU r_num;static int utmp_fd = -1;int utmp_open (char * filename) {utmp_fd = open (filename,o_rdonly); Cur_num = 0; Utmp_num = 0; return UTMP_FD;} struct utmp * Utmp_next () {struct utmp * next; if (utmp_fd = =-1) return utnull; if (Cur_num = = Utmp_num && utmp_reload () = = 0) return utnull; Next = (struct utmp *) &utmp_buffer[UTSIZE*cur_num]; cur_num++; return next;} int utmp_reload () {int len = read (utmp_fd,utmp_buffer,utsize*nrecs); Utmp_num = len/utsize; Cur_num = 0; return utmp_num;} void Utmp_close () {if (utmp_fd! =-1) close (UTMP_FD);
Who.c
#include "utmplib.c" #include <sys/types.h> #include <utmp.h> #include <fcntl.h> #include <time.h >void show_info (struct utmp *); void Showtime (time_t); int main () {printf ("%s", utmp_file); struct utmp * utmp_buffer; int fd;if (FD = Utmp_open (utmp_file)) = =-1) return-1;//utmp_reload (); while ((Utmp_buffer = Utmp_next ())! = Utnull) Show_ info (utmp_buffer); Utmp_close (); return 0;} void Show_info (struct utmp * buffer) {if (Buffer->ut_type! = user_process)//utmp structure has a Ut_type member, when it is user_process, Indicates that this is an already logged-on user return;printf ("%-8.8s", Buffer->ut_name);p rintf ("");p rintf ("%-8.8s", Buffer->ut_line);p rintf ( ""); Showtime (Buffer->ut_time); #ifdef showhostif (buffer->ut_host[0]! = ' buffer->ut_host ') printf ("(%s)" ); #endifprintf ("\ n");} void Showtime (time_t time) {char * CP;CP = CTime (&time);p rintf ("%12.12s", cp+4);}
Who to write the shell command yourself