After reading the "Linux/unix system Programming Manual" and apue the previous chapters found that the lack of appropriate practice, if it is simply to understand the API does not make much sense, so decided to follow the "Unix/linux Programming Practice Tutorial" will be the example of the book to understand through. Then to chew Apue, the effect should be much better.
The second chapter of the book gives the WHO implementation, because the writing and 2004, the code looks somewhat "alternative", for the compilation of problems found in the process of revision, before explaining the code to record the following usage:
Grep-r command
-R,--recursive
Read All Files under each directory, recursively, following symbolic Links only if they are on the command line. Note this if no file operand is given, grep searches the working Directory. This is equivalent to the-d recurse option.
-R,--dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike-r.
For example, the following command Grep-n-R ' Utmp_file '/usr/include
is to find the string utmp_file recursively in the/usr/include directory.
The difference between-R and-R is different for symbolic links.
#include <stdio.h> #include <stdlib.h> #include <utmp.h> #include <fcntl.h> #include <
unistd.h> #include <time.h> void Showtime (Long);
void Show_info (struct utmp * UTBUFP);
int main () {struct utmp current_record;
int UTMPFD;
int reclen = sizeof (Current_record);
if ((UTMPFD = open (Utmp_file, o_rdonly)) = = 1) {perror (utmp_file);
Exit (1);
while (read (UTMPFD, ¤t_record, reclen) = = Reclen) show_info (¤t_record);
Close (UTMPFD);
return 0;
} void Show_info (struct utmp *utbufp) {if (Utbufp->ut_type!=) return;
printf ("%-8.8s", utbufp->ut_name);
printf ("%-8.8s", utbufp->ut_line);
Showtime (Utbufp->ut_time);
#ifdef showhost if (utbufp->ut_host[0]!= ') printf ("(%s)", utbufp->ut_host);
#endif printf ("\ n");
} void Showtime (Long timeval) {char *cp; Cp = CTime (&timeval);
printf ("%12.12s", CP + 4); }
In the above program Utmp_file is _path_utmp by grep, using grep to know its value as/var/run/utmp in the same way.
READ: The file offset is recorded for each open file system kernel, and sometimes the file offset is also referred to as read-write offset or pointer. A file offset is a file or start position that executes the next read () or write () operation, expressed as the current location of the file relative to the starting point of the file's head.
CTime function to enter a pointer to time_t, the time string returned is similar to the following format:
Wed June 21:49:08 1993\n
Since the WHO command does not need to indicate the day of the week, output in the program starts at the 4th character. Using buffer technology
Get 16 record data at a time, in this way you can reduce the number of read calls to the original 1/16.
#include <stdio.h> #include <stdlib.h> #include <utmp.h> #include <fcntl.h> #include < unistd.h> #include <time.h> #define SHOWHOST/*include remote machine on output*/#define NRECS #define Nullut ((struct utmp*) NULL) #define UTSIZE (sizeof (struct utmp)) static char utmpbuf[nrecs* utsize]; /*storage*/static int num_recs; /*num stored*/static int cur_rec; /*next to go */static int fd_utmp =-1;
/*read from*/int Utmp_open (char* filename) {fd_utmp = open (filename,o_rdonly);
Cur_rec = num_recs = 0;
return fd_utmp;
int utmp_reload ()/*read next bunch of records into buffer*/{int amt_read;
Amt_read = Read (fd_utmp,utmpbuf,nrecs*utsize);
Num_recs = amt_read/utsize;
Cur_rec = 0;
return num_recs;
} struct utmp* Utmp_next () {struct utmp* RECP;
if (fd_utmp = = 1) return nullut;
if (Cur_rec = = Num_recs && utmp_reload () = = 0) return nullut; ReCP = (struct utmp*) &utmpbuf[cur_rec * Utsize];
Cur_rec + +;
return RECP;
} void Utmp_close () {if (fd_utmp!=-1) close (fd_utmp);}
void Showtime (Long Timeval) {char* cp;
CP = CTime (&timeval);
printf ("%12.12s", cp+4); } void Show_info (struct utmp* utbufp) {/*user_process indicate the USER is active or not*/if (utbufp->ut_type!
= user_process) return; printf ("%-8.8s", utbufp->ut_name); /*this logname */printf ("%-8.8s", utbufp->ut_line);
/*the logtty*/Showtime (Utbufp->ut_time); #ifdef showhost if (utbufp->ut_host[0]!= ') printf ("(%s)", utbufp->ut_host);
/*the host*/#endif printf ("\ n"); int main () {struct utmp *utbufp;/*read info into here*/int utmpfd;
/*read from the descriptor*/if (Utmp_open (utmp_file) = = 1) {perror (utmp_file);
Exit (1);
while ((UTBUFP =utmp_next ())!= ((struct utmp*) NULL) {Show_info (UTBUFP);
} utmp_close ();
return 0; }