tac(1) command using mmap(2)

Intro

A small and efficient tac(1) UNIX® filter application written while learning mmap(1). Using this as a base case more complex programs can programmed as: tail(1) and head(1).

Usage

The tac.c source code.

$ gcc -Wall tac.c -o tac
$ ./tac tac.c | ./tac
/*
 * $File: tac.c A small and efficient tac(1) using mmap(2)
 * $URL: http://speirofr.appspot.com/files/tac.c
 * $Author: Salva Peiró <speirofr@gmail.com> (c) Copyright 2014.
 * $License: GPLv2.
 */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>

int main(int argc, char *argv[])
{
    int fd, n;
    char *data, *prev, *ptr;
    if (argc>1 && (fd=open(argv[1], O_RDONLY)) < 0)
        return -1;
    n = lseek(fd, 0, SEEK_END);
    data = mmap(NULL, n, PROT_READ, MAP_PRIVATE, fd, 0);
    if(data==MAP_FAILED)
        return -1;
    ptr = prev = data + n - 1;
    while (prev >= data) {
        if (*prev == '\n') prev--;
        while (prev >= data && *prev != '\n') prev--;
        write (1, prev+1, ptr - prev);
        ptr = prev;
    }
    munmap(data, n);
    return 0;
}
/*
 gcc -Wall tac.c -o tac && ./tac tac.c # */