你的位置:首页 > 操作系统

[操作系统]head/tail实现


     只实现了head/tail的基本功能,默认显示十行及-n参数。
     
  一、使用带缓冲的系统调用。
     
  write/read等系统调用是不带缓冲的,可以包装一层,使其带缓冲。
typedef struct{  int rio_fd;  int rio_cnt;  char *rio_bufptr;  char rio_buf[RIO_BUFFSIZE];}rio_t; void rio_readinitb(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

     二、head命令实现


#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 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

     三、tail命令实现


#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 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

     通过递归show_info来实现按顺序打印,其实也可以用链表来实现,不过递归写起来简单。