User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

c:tail-example [2018-08-01 13:44] (current)
Line 1: Line 1:
 +=====Pure C tail example with usleep======
 +
 +<code c tail.c>
 +/* $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 */
 +</​code>​
 +
 +
 +----
 +
 +[<>]