File: tailf.c

package info (click to toggle)
apmd 3.0beta5-1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 244 kB
  • ctags: 106
  • sloc: ansic: 1,047; sh: 119; makefile: 109
file content (112 lines) | stat: -rw-r--r-- 3,127 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* tailf.c -- tail a log file and then follow it
 * Created: Tue Jan  9 15:49:21 1996 by r.faith@ieee.org
 * Revised: Thu Jan 11 16:47:20 1996 by r.faith@ieee.org
 * Copyright 1996 Rickard E. Faith (r.faith@ieee.org)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 * $Id: tailf.c,v 1.1 1996/01/11 21:51:07 faith Exp $
 *
 * less -F and tail -f cause a disk access every five seconds.  This
 * program avoids this problem by waiting for the file size to change.
 * Hence, the file is not accessed, and the access time does not need to be
 * flushed back to disk.  This is sort of a "stealth" tail.
 */

#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/stat.h>

size_t filesize( const char *filename )
{
   struct stat sb;

   if (!stat( filename, &sb )) return sb.st_size;
   return 0;
}

void tailf( const char *filename, int lines )
{
   char **buffer;
   int  head = 0;
   int  tail = 0;
   FILE *str;
   int  i;

   if (!(str = fopen( filename, "r" ))) {
      fprintf( stderr, "Cannot open \"%s\" for read\n", filename );
      perror( "" );
      exit( 1 );
   }

   buffer = malloc( lines * sizeof( char * ) );
   for (i = 0; i < lines; i++) buffer[i] = malloc( BUFSIZ + 1 );

   while (fgets( buffer[tail], BUFSIZ, str )) {
      if (++tail >= lines) {
	 tail = 0;
	 head = 1;
      }
   }

   if (head) {
      for (i = tail; i < lines; i++) fputs( buffer[i], stdout );
      for (i = 0; i < tail; i++)         fputs( buffer[i], stdout );
   } else {
      for (i = head; i < tail; i++) fputs( buffer[i], stdout );
   }
   fflush( stdout );

   for (i = 0; i < lines; i++) free( buffer[i] );
   free( buffer );
}

int main( int argc, char **argv )
{
   char        buffer[BUFSIZ];
   size_t      osize, nsize;
   FILE        *str;
   const char  *filename;
   int         count;
   
   if (argc != 2) {
      fprintf( stderr, "Usage: tailf logfile\n" );
      exit( 1 );
   }

   filename = argv[1];
   
   tailf( filename, 10 );
   
   for (osize = filesize( filename );;) {
      nsize = filesize( filename );
      if (nsize != osize) {
	 if (!(str = fopen( filename, "r" ))) {
	    fprintf( stderr, "Cannot open \"%s\" for read\n", filename );
	    perror( argv[0] );
	    exit( 1 );
	 }
	 fseek( str, osize, SEEK_SET );
	 while ((count = fread( buffer, 1, sizeof( buffer ), str )) > 0)
	    fwrite( buffer, 1, count, stdout );
	 fflush( stdout );
	 fclose( str );
	 osize = nsize;
      }
      usleep( 250000 );		/* 250mS */
   }
   return 0;
}