Venkatesh Joshi wrote:

> I would like to know how to implement "tail -n" in C.

Use a circular buffer which contains the last N lines read. Each time
you read a line, remove the first line and add the new line to the end
of the buffer. When you reach the end, display the contents of the
buffer.

E.g.

void tail(FILE *fp, int num_lines)
{
        char **buffer = calloc(num_lines, sizeof(char *));
        int index = 0;
        int i;

        for (;;)
        {
                char *line = NULL;
                int len = 0;

                if (getline(&line, &len, fp) < 0)
                        break;

                if (buffer[index])
                        free(buffer[index]);

                buffer[index] = line;

                index++;
                index %= num_lines;
        }

        for (i = 0; i < num_lines; i++)
                puts(buffer[(index + i) % num_lines]);
}

In practice, you would probably want to do your own memory allocation
rather than using getline(). You also need to allow for files with
less than num_lines lines..

> The "-n" option will be used to print the last n lines of a file -
> rather than the default option of printing the last 10 lines of a file.
> 
> I wish to do this in a single pass. I can use lseek() to go to the end
> of the file. How to traverse backwards from there ? Is there any
> function that does this ?

Use lseek(SEEK_CUR) with a negative offset to seek backwards. You
would have to use trial and error to determine how much you need to
read.

Also, lseek() will only work on regular files. It won't work on pipes,
etc. The "tail" command works on pipes.

-- 
Glynn Clements <[EMAIL PROTECTED]>
-
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" 
in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to