User Tools

Site Tools


Pure C tail example with usleep

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 */

First PagePrevious PageBack to overviewNext PageLast Page