/**************************************************************
> File Name: tail.c
> Author: 逮枫灵
> mail: Albert@sshenp.com
> Created Time: 2020年06月13日 星期六 20时55分43秒
**************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFF_SIZE 1024
int strchrcnt(char *src, char c);
off_t get_start(int n);
void tail_print(int n);
const char *filename;
off_t offset;
int fd;
int main(int argc, char *argv[])
{
int n = 10;
if(argc == 4 || argc == 3 && strncmp(argv[1], "-n", 2) == 0)
{
char *endptr;
char *invalid_num;
if(argc == 4)
{
n = strtol(argv[2], &endptr, 10);
invalid_num = argv[2];
filename = argv[3];
}
else if(argc == 3)
{
n = strtol(argv[1] + 2, &endptr, 10);
invalid_num = argv[1] + 2;
filename = argv[2];
}
if(*endptr != '\0')
{
fprintf(stderr, "tail: 无效的号码%%s: \"%s\"\n", invalid_num);
exit(1);
}
}
tail_print(n);
return 0;
}
int strchrcnt(char *src, char c)
{
int count = 0;
if(src)
{
while(*src != '\0')
{
if(*src++ == c)
count++;
}
}
return count;
}
void tail_print(int n)
{
get_start(n);
char file_text[BUFF_SIZE + 1];
memset(file_text, 0, BUFF_SIZE + 1);
lseek(fd, offset, SEEK_SET);
int cn = 0;
while((cn = read(fd, file_text, BUFF_SIZE)) > 0)
{
write(STDOUT_FILENO, file_text, cn);
}
}
off_t get_start(int n)
{
if((fd = open(filename, O_RDONLY)) == -1)
{
perror("open failed");
exit(1);
}
int ln_count = 0;
int of_count = BUFF_SIZE;
off_t pre_offset = lseek(fd, 0, SEEK_END);
char buffer[BUFF_SIZE + 1] = {0};
while(ln_count <= n)
{
offset = lseek(fd, -of_count, SEEK_END);
if(offset == -1)
{
offset = lseek(fd, 0, SEEK_SET);
read(fd, buffer, pre_offset);
buffer[pre_offset + 1] = '\0';
//printf("%s\n", buffer);
ln_count += strchrcnt(buffer, '\n');
offset = 0;
break;
}
of_count += read(fd, buffer, BUFF_SIZE);
ln_count += strchrcnt(buffer, '\n');
pre_offset = offset;
}
int ln_over = ln_count - n + 1;
char *index = buffer;
// ln_over could be less than 0
while(--ln_over > 0)
{
index = strchr(index, '\n');
index++;
}
offset += index - buffer;
return offset;
}
版权声明:本文为qq_40162781原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。