How can I see if I have reached beginning of file?

Viewed 473

I have a task to rewrite the Unix system function tail. My algorithm works in the following way:

I lseek to the end of the file, enter a loop, move the file descriptor a bit back, read a couple of bytes, and if I find any new lines, I increase the counter. Once, I get 10 new lines ( I think it should be 11, but the thing is not finished yet and this works for me for now ), I leave the loop.


If the file has less than 10 new lines, I get into an infinite loop, because of the way I wrote it.

Is there a way to see if I have reached the beginning of the file, so I can leave the loop then?

Code :

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main (int argc, char *argv[])
{

    int fd;
    off_t offset = 10;
    size_t size = 10;
    unsigned char buff[10];
    int new_line_counter = 0;
    off_t total_offset = 0;//dont mind this
    fd = open("a.txt", O_RDONLY);
    if (fd == -1)
    {
        perror("open");
        return 1;
    }
    lseek(fd,0,SEEK_END);
    while (new_line_counter < 10)
    {
        lseek(fd,-offset,SEEK_CUR);
        total_offset+=10;//dont mind this
        for(int i = 0; i<10;i++)
        {
            if(buff[i]=='\n')
            {   
                if(new_line_counter==10)break;
                new_line_counter++;
                //printf("%d",new_line_counter);
            
            }
        }
        read(fd,buff,size);
        lseek(fd,-offset,SEEK_CUR);
    }
}
2 Answers

Use the return value of lseek. It will return the current file position, or, -1 on error.

You first lseek(fd,0,SEEK_END) will give you the file size.

Use that to keep track the current file position (and make sure that to adjust 'offset' so that lseek(fd,-offset,SEEK_CUR); will never seek before file begin.

This is necessary, otherwise you might miss the first line.

lseek() returns a value, it's either the new offset or -1. Check for that value like this:

    while (new_line_counter < 10)
    {
        if (-1==lseek(fd,-offset,SEEK_CUR)) break;
Related