Head/tail implementation and headtail implementation
Only the basic head/tail functions are implemented. By default, 10 rows and-n parameters are displayed. 1. Use a system call with buffer. System calls such as write/read are not buffered. You can wrap a layer to buffer it. Typedef struct {int rio_fd; int rio_cnt; char * handle; char rio_buf [RIO_BUFFSIZE];} rio_t; void trim (rio_t * rp, int fd) {rp-> rio_fd = fd; rp-> rio_cnt = 0; rp-> rio_bufptr = rp-> rio_buf;} ssize_t rio_read (rio_t * rp, void * usrbuf, size_t n) {int cnt = 0; while (rp-> rio_cnt <= 0) {if (rp-> rio_cnt = read (rp-> rio_fd, rp-> rio_buf, sizeof (rp-> rio_buf ))) <0) {if (errno! = EINTR) {return-1 ;}} else if (rp-> rio_cnt == 0) {return 0 ;}else {rp-> rio_bufptr = rp-> rio_buf ;}} // cnt = n> rp-> rio_cnt? Rp-> rio_cnt: n; cnt = n; if (n> rp-> rio_cnt) {cnt = rp-> rio_cnt;} memcpy (usrbuf, rp-> rio_bufptr, cnt); rp-> rio_cnt-= cnt; rp-> rio_bufptr + = cnt; return cnt;} ssize_t rio_readlineb (rio_t * rp, void * usrbuf, size_t maxlen, int count) {int I = 0, rc = 0, num = 0; char c = 0, * buf = usrbuf; lseek (rp-> rio_fd, maxlen, SEEK_END ); for (I = 1; I <maxlen; I ++) {if (rc = rio_read (rp, & c, 1) = 1) {* buf ++ = c; if (c = '\ n') {if (++ num = count) {break ;}}} else if (rc = 0) {if (I = 1) {return 0 ;}else {break ;}} else {return-1 ;}} * buf = '\ 0'; return I ;}View Code
Ii. head command implementation
# Include <stdio. h> # include <stdlib. h> # include <fcntl. h> # include <unistd. h> # include <string. h> # include "rio. h "# define MAXSIZE 4096 int main (int argc, char ** argv) {if (argc <2) {fprintf (stderr, "usage % s [-n] filename \ n", argv [0]); return-1;} int times = 10, I = 0, in_fd =-1, n_char = 0; char filename [16] = {0}; char buf [MAXSIZE] = {0}; rio_t rio_buf = {0}; for (I = 1; I <argc; I ++) {if (! Strcmp (argv [I], "-n") {times = atoi (argv [++ I]);} else {snprintf (filename, sizeof (filename ), "% s", argv [I]) ;}} if (in_fd = open (filename, O_RDONLY) ==-1) {fprintf (stderr, "open % s failed \ n", filename); return-1;} rio_readinitb (& rio_buf, in_fd); if (n_char = rio_readlineb (& rio_buf, buf, MAXSIZE, times)> 0) {write (STDOUT_FILENO, buf, n_char);} close (in_fd); return 0 ;}View Code
Iii. tail command implementation
# Include "rio. h "# define MAXSIZE 4096 void show_info (char * buf, char ** ptr, int count); int main (int argc, char ** argv) {if (argc <2) {fprintf (stderr, "usage % s [-n] filename \ n", argv [0]); return-1;} int times = 10, I = 0, in_fd =-1; char filename [16] = {0}; char buf [MAXSIZE] = {0}; rio_t rio_buf = {0}; char * ptr [MAXSIZE]; for (I = 1; I <argc; I ++) {if (! Strcmp (argv [I], "-n") {times = atoi (argv [++ I]);} else {snprintf (filename, sizeof (filename ), "% s", argv [I]) ;}} if (in_fd = open (filename, O_RDONLY) ==-1) {fprintf (stderr, "open % s failed \ n", filename); return-1;} rio_readinitb (& rio_buf, in_fd); rio_read (& rio_buf, buf, MAXSIZE); show_info (buf, ptr, times); return 0;} void show_info (char * buf, char ** ptr, int times) {int num = 0; int flag = 0; if (num <times) {* ptr = strrchr (buf, '\ n'); flag = 1; ** ptr =' \ 0'; show_info (buf, ptr + 1, -- times);} if (flag) {printf ("% s \ n", * ptr + 1 );}}View Code
Recursive show_info can be used to print data in sequence. In fact, it can also be implemented using a linked list. Recursive writing is simple.