/* $Id: main.c,v 1.1 2016/08/14 23:47:57 root Exp root $ */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <err.h> #include <sys/stat.h> struct file_info { FILE *fp; char *filename; struct stat st; }; typedef struct file_info file_info_t; void _log(char* format, const char* str) { fprintf(stderr, format, str); } int main ( int argc, char** argv ) { char* filename = "/var/log/debug.log"; file_info_t* file; struct stat st2; char buf[BUFSIZ]; fpos_t pos; file = (file_info_t*) malloc(sizeof(struct file_info)); if (!file) { err(1, "Couldn't malloc space for file descriptors."); } file->filename = strdup(filename); if (!file->filename) errx(1, "Couldn't malloc space for file name."); if ((file->fp = fopen(file->filename, "r")) == NULL || fstat(fileno(file->fp), &file->st)) { if (file->fp != NULL) { fclose(file->fp); file->fp = NULL; } } _log("Try open file: %s\n", file->filename); if ((file->fp = fopen(file->filename, "r")) == NULL) { _log("Cannot open file: %s\n", file->filename); exit(EXIT_FAILURE); } if (fseek(file->fp, 0, SEEK_END) != 0) { _log("Cannot read file: %s\n", file->filename); exit(EXIT_FAILURE); } if (fgetpos(file->fp, &pos) == -1) { _log("Cannot position file: %s\n", file->filename); exit(EXIT_FAILURE); } for (;;) { fgets(buf, BUFSIZ, file->fp); if (ferror(file->fp)) { _log("Error reading file: %s\n", file->filename); exit(EXIT_FAILURE); } if (stat(file->filename, &st2) == -1) { _log("Ups, file %s closed...\n", file->filename); if (file->fp != NULL) { fclose(file->fp); file->fp = NULL; } } // if (st2.st_ino == file->st.st_ino && st2.st_dev == file->st.st_dev && st2.st_nlink != 0) { // _log("The same file %s\n", file->filename); // } if (st2.st_ino != file->st.st_ino || st2.st_dev != file->st.st_dev || st2.st_nlink == 0) { _log("Ups, file %s changed...\n", file->filename); file->fp = freopen(file->filename, "r", file->fp); if (file->fp != NULL) { memcpy(&file->st, &st2, sizeof(struct stat)); } else { _log("Cannot reopen file %s\n", file->filename); } } if (feof(file->fp)) { fsetpos(file->fp, &pos); clearerr(file->fp); (void) usleep(250000); continue; } fgetpos(file->fp, &pos); printf("%s", buf); fflush(stdout); } if (file->fp != NULL) { fclose(file->fp); file->fp = NULL; } free(file); return 1; } /* EOF */