Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //------------------------------------------------------------------------
- // NAME: Stefan Grozev
- // CLASS: XIa
- // NUMBER: 25
- // PROBLEM: #1
- // FILE NAME: tail.c (unix file name)
- // FILE PURPOSE: this is the file containing the main() function
- // няколко реда, които описват накратко
- // предназначението на файла
- // ...
- // Този файл съдържа main() фукнцията, в която са дефинирани променливите
- // и извиква дефинираните и инициализирани функции, които четат броя на
- // аргументите(имената на файловете), отварят ги, принтират в тандартния
- // изход (stdout), разделени със заглавна секция.
- //------------------------------------------------------------------------
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
- // printing the last 10 lines of a file
- void print_last_lines(int file, const char *filename);
- // printing the last 10 lines of a standard input
- void st_input(int fd);
- // checks if the arguement is a directory
- int is_regular_file(const char *path);
- int main(int argc, char const *argv[]) {
- // стринг в който се записва грешката от perror
- char str[500];
- ssize_t written = 0;
- // sets a file descriptor for every file
- if(argc == 1){
- int fd = open("temporaryfile.txt", O_CREAT | O_RDWR);
- st_input(fd);
- print_last_lines(fd, argv[1]);
- }
- for(int i = 1; i < argc; i++){
- // проверява дали подаденият аргумент е '-' и ако е true създава
- // файлов дескриптор сочещ към нов празен файл "temporary.txt"
- // и извиква функциите st_input и print_last_lines (на долу са описани)
- if(!strcmp(argv[i], "-")){
- int fd = open("temporaryfile.txt", O_CREAT | O_RDWR);
- st_input(fd);
- print_last_lines(fd, argv[i]);
- }else{
- // създава файлов дескриптор сочещ към текущият аргумент(файл)
- int file = open(argv[i], O_RDONLY);
- // създава променлива съдържаща резултата от функцията is_regular_file
- // с аргумент текущия файл
- int is_regular = is_regular_file(argv[i]);
- // изписва заглавие с името на файла, ако са подадени повече от 1 файл
- // и open() е върнала положителен резултат
- if(argc > 2 && file > 0){
- write(STDOUT_FILENO, "==> ", 4);
- write(STDOUT_FILENO, argv[i], strlen(argv[i]));
- write(STDOUT_FILENO, " <==\n", 5);
- }
- // съобщение за грешка при проблем с отварянето на файла
- if(file <= 0){
- //проверява дали подаденият аргумент е директория
- if(is_regular < 0){
- sprintf(str, "tail: error reading '%s'", argv[i]);
- perror(str);
- }else{
- sprintf(str, "tail: cannot open '%s' for reading", argv[i]);
- perror(str);
- }
- // ако няма грешка чете файла и изписва съдържанието му в стандартния изход
- }else{
- print_last_lines(file, argv[i]);
- // Принтира нов пред след последния байт от текущия файл и преди заглавието
- // на следващият
- if(argc > 2 && i < argc - 1){
- write(STDOUT_FILENO, "\n", 1);
- }
- close(file);
- }
- }
- }
- return 0;
- }
- //------------------------------------------------------------------------
- // FUNCTION: void print_last_lines (име на функцията)
- // предназначение на функцията : принтира последните 10 реда от файл
- // PARAMETERS: int argc(брой подадени файлове), files[argc], масив съдържащ
- // файловите дескриптори за всеки файл.
- // списък с параметрите на функцията
- // и тяхното значение: buff: буфер в който се записва информацията от
- // подадения файл и я записва във стандартният изход, written: съдържа
- // резултата колко символа функцията write() е успяла да запише успешно,
- // len: съдържа резултата колко символа функцията read() е успяла да прочете
- // от подадения файл, pos: contains the offset of the pointer ( in bytes)
- // from the beginning of the file, total_lines: брояч, който се увеличава
- // всеки път когато char C е получила стойността '\n' и при достигане на 10
- // прекратява цикъла, c: read() функцията записва прочетения байт в нея и
- // ако е нов ред увеличава total_lines с 1
- //------------------------------------------------------------------------
- void print_last_lines(int file, const char *filename){
- char buff[255];
- ssize_t written;
- int len = 1;
- int reading = 1;
- off_t pos = lseek(file, 0, SEEK_END);
- size_t total_lines = 0;
- char c;
- //отмества offset-a от края на файла към началото докато не стигне 10-я ред
- while(pos){
- lseek(file, --pos, SEEK_SET);
- reading = read(file, &c, 1);
- if(reading > 0){
- if(c == '\n'){
- if(total_lines == 10) {
- break;
- } else {
- total_lines++;
- }
- }
- }
- // проверка дали функцията read() се е изпълнила успешно
- else if(reading < 0){
- sprintf(buff, "tail: error reading '%s'", filename);
- perror(buff);
- }
- }
- // short files handling
- if(c != '\n'){
- write(STDOUT_FILENO, &c, 1);
- }
- // изписва съдържанието на подадения файл в стандартният изход
- // докато read() връща стойност различна от 0
- while(len != 0){
- len = read(file, buff, 255);
- if(len == 0){
- break;
- }
- //проверка дали read() функцията се е изпълнила успешно
- else if(len < 0){
- sprintf(buff, "tail: error reading '%s'", filename);
- perror(buff);
- }
- //записва байт по байт прочетената от файла и записана в
- //буфера информация докато write() не върне 0 (не е записала
- // нищо) или броя на записаните байтове (i) стане равен на
- // броя прочетени байтове (len)
- for(size_t i = 0; i < len; i++){
- written = write(STDOUT_FILENO, buff + i, 1);
- if(written == 0){
- break;
- }
- }
- }
- }
- //------------------------------------------------------------------------
- // FUNCTION: st_input (име на функцията)
- // предназначение на функцията: чете от стандартния вход и записва данните
- // във нов файл озаглавен temporary.txt
- // PARAMETERS: fd(file descriptor-a на новосъздаденият файл temporary.txt)
- // списък с параметрите на функцията
- // и тяхното значение: data: буфер в който се записва информацията от
- // стандартният вход и я записва във temporary.txt, written: съдържа
- // резултата колко символа функцията write() е успяла да запише успешно,
- // len: съдържа резултата колко символа функцията read() е успяла да прочете
- // от стандартният вход
- //------------------------------------------------------------------------
- void st_input(int fd){
- char data[128];
- ssize_t written;
- int len = 1;
- while(len != 0){
- len = read(0, data, 128);
- if(len == 0){
- break;
- }
- for(size_t i = 0; i < len; i++){
- written = write(fd, data + i, 1);
- if(written == 0){
- break;
- }
- }
- }
- }
- //------------------------------------------------------------------------
- // FUNCTION: is_regular_file (име на функцията)
- // предназначение на функцията: Проверява дали подадения аргумент е директория
- // PARAMETERS: подадения аргумент през стандартния вход
- // списък с параметрите на функцията
- // и тяхното значение
- //------------------------------------------------------------------------
- int is_regular_file(const char *path)
- {
- struct stat path_stat;
- stat(path, &path_stat);
- return S_ISREG(path_stat.st_mode);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement