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;
}