C Program to Realization On The Unix Tail Command

How to write a C Program to  Realization On The Unix Tail Command in C Programming Language ?

Solution For C Program :

/*Realization on the Unix tail command*/

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

#define LINE_COUNT 10
#define BUFFER_SIZE 200
#define MAX_STDIN_SIZE 199999

//--------------------------------------------
// FUNCTION: open_error
// Function for writing error if open is unsuccessful
// PARAMETERS: char* file_name
// file_name : gets string that contents the text files name
// perror() : sets the global variable errno to indicate the error type.
//----------------------------------------------
void open_error(char* file_name) {        
       write(STDOUT_FILENO, "tail: cannot open '", 19);
       write(STDOUT_FILENO, file_name, strlen(file_name));
       write(STDOUT_FILENO, "' for reading", 13);
  perror(" ");
}

//--------------------------------------------
// FUNCTION: write_fileName
// Function for writing the section of the file name
// PARAMETERS: char* file_name
// file_name : gets string that contents the text files name
//----------------------------------------------
void write_fileName(char* file_name) {
        write(STDOUT_FILENO, "==> ", 4);
        write(STDOUT_FILENO, file_name, strlen(file_name));
        write(STDOUT_FILENO, " <==\n", 5);
}

//--------------------------------------------
// FUNCTION: read_stdin
// Function for reading and writing on the standart I/O
// PARAMETERS:
// line_count : count the lines
// char line[] : read a line from the input
// char lines[10][] : copy the last 10 line[]
//----------------------------------------------
void read_stdin() {
    int line_count = 0, counter;
    char* line;
    char** lines = (char**)malloc(LINE_COUNT * sizeof(lines));
    char next_in;
    void* new_element;
   
    line = (char* )malloc(2 * sizeof(line));
    int char_count = 1;
   
    while(read(STDIN_FILENO, &next_in, 1) > 0) {
   
    if(next_in == '\n') {
   
    if(line_count == LINE_COUNT) {        
          for(counter = 1 ; counter <= LINE_COUNT; counter ++) {
               strcpy(lines[counter - 1], lines[counter]);
            }
         
            strcpy(lines[line_count], line);
        }else{
        new_element = realloc(lines, strlen(line) * sizeof(lines));
        lines = new_element;
            strcpy(lines[line_count ++], line);
            printf("%d\n", line_count);
        }
        }else{
        line[char_count] = next_in;
        char_count ++;
    new_element = realloc(line, (char_count + 1) * sizeof(line));
   
if(new_element != NULL) {
line = new_element;
}else{
perror("Out of memory");
}
}
    }
 
    for(counter = 0; counter < line_count; counter ++) {
        write(STDOUT_FILENO, lines[counter], strlen(lines[counter]));
    }
}

int main (int argc, char *argv[]) {
     
        int file_desc ;
        int read_status, written_bits;
        int counter, line_counter;
        char buffer[BUFFER_SIZE];
        char character[1];
     
        for(counter = 1; counter < argc ; counter ++) {
       
        if(strcmp(argv[counter], "-") == 0) {
        write(STDOUT_FILENO, "==> standart input <== \n", 24);
      read_stdin();
        } else {
        file_desc = open(argv[counter], O_RDONLY) ;
        if (file_desc == -1) { // If the open is unsuccessful, it returns -1
open_error(argv[counter]);              
return 1;
}

if(argc > 2) {
    write_fileName(argv[counter]);
        }

        lseek(file_desc, -1, SEEK_END);   // Go to the end of the file -1 one bit
                                                 // because of the read in the start of the do.. while
        line_counter = 0;
        read_status = 0;
         
        // Read char by char until lseek spits the 0(start of file)
        // Or we get a read_status == 0(End of file EOF) (Only 1 char in file)
do {
read_status = read(file_desc, character, 1);
                if(read_status == -1) {                      // Error checking
                if(errno == EINTR) {
read_status = 0;
}else{
perror("tail ");
return 1;
}

}
// Read return 0 when indicates the end of file
                if(read_status == 0) {
                lseek(file_desc, 0, SEEK_SET);
                break;
                }
               
                if(character[0] == '\n') {
                  line_counter++;
                }
             
                if(LINE_COUNT - line_counter < 0) {
                break;
                }
            } while(lseek(file_desc, -2, SEEK_CUR));
           
            // Read string and then write on the standart output
            while(1) {
   
        int read_bits = read(file_desc, buffer, BUFFER_SIZE);
        if(read_bits < 0) {
            perror("tail: Read error occured");
                break;
        } else if(read_bits == 0) {
            break;
        }

        written_bits = write(STDOUT_FILENO, buffer, read_bits);  
        if(written_bits < 0) {
            perror("taile: Write error occured");
            break;
        }
    }

    // Check if the close function is unsuccessful
            int close_status = close(file_desc);
            if(file_desc == -1) {
            perror("tail");
            return 1 ;
            }
             }    
        }

        return 0;
}


Learn More :