From owner-freebsd-hackers Tue Feb 10 09:18:05 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id JAA02276 for hackers-outgoing; Tue, 10 Feb 1998 09:18:05 -0800 (PST) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from cynic.portal.ca (root@cynic.portal.ca [204.174.36.7]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id JAA02230 for ; Tue, 10 Feb 1998 09:17:56 -0800 (PST) (envelope-from cjs@portal.ca) Received: from localhost ([[UNIX: localhost]]) by cynic.portal.ca (8.8.5/8.8.5) with SMTP id JAA05718; Tue, 10 Feb 1998 09:17:38 -0800 (PST) X-Authentication-Warning: cynic.portal.ca: cjs owned process doing -bs Date: Tue, 10 Feb 1998 09:17:37 -0800 (PST) From: Curt Sampson X-Sender: cjs@cynic.portal.ca Reply-To: cjs@netbsd.org, freebsd-hackers@FreeBSD.ORG To: freebsd-hackers@FreeBSD.ORG, support@bsdi.com Subject: tail -F patches Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG This was really popular with the NetBSD crowd, so I thought I'd forward it on to you folks. The following patches to tail(1) add a -F option which will make it continue to follow data appended to a file even if the file is rotated by newsyslog(8) or something similar, or truncated. cjs Curt Sampson cjs@portal.ca Info at http://www.portal.ca/ Internet Portal Services, Inc. Through infinite mist, software reverberates Vancouver, BC (604) 257-9400 In code possess'd of invisible folly. Index: forward.c =================================================================== RCS file: /cvsroot/src/usr.bin/tail/forward.c,v retrieving revision 1.8 diff -u -r1.8 forward.c --- forward.c 1997/10/19 23:45:08 1.8 +++ forward.c 1998/02/09 19:21:43 @@ -91,6 +91,15 @@ { int ch; struct timeval second; + int dostat = 0; + struct stat statbuf; + off_t lastsize = 0; + dev_t lastdev; + ino_t lastino; + + /* Keep track of file's previous incarnation. */ + lastdev = sbp->st_dev; + lastino = sbp->st_ino; switch(style) { case FBYTES: @@ -166,9 +175,11 @@ } for (;;) { - while ((ch = getc(fp)) != EOF) + while ((ch = getc(fp)) != EOF) { + lastsize++; /* track size changes between stats */ if (putchar(ch) == EOF) oerr(); + } if (ferror(fp)) { ierr(); return; @@ -186,6 +197,39 @@ if (select(0, NULL, NULL, NULL, &second) == -1) err(1, "select: %s", strerror(errno)); clearerr(fp); + + if (fflag == 1) + continue; + /* + * We restat the original filename every five seconds. If + * the size is ever smaller than the last time we read it, + * the file has probably been truncated; if the inode or + * or device number are different, it has been rotated. + * This causes us to close it, reopen it, and continue + * the tail -f. If stat returns an error (say, because + * the file has been removed), just continue with what + * we've got open now. + */ + if (dostat > 0) { + dostat -= 1; + } else { + dostat = 5; + if (stat(fname, &statbuf) == 0) { + if (statbuf.st_dev != lastdev || + statbuf.st_ino != lastino || + statbuf.st_size < lastsize) { + lastdev = statbuf.st_dev; + lastino = statbuf.st_ino; + lastsize = 0; + fclose(fp); + if ((fp = fopen(fname, "r")) == NULL) + err(1, "can't reopen %s: %s", + fname, strerror(errno)); + } else { + lastsize = statbuf.st_size; + } + } + } } } Index: tail.1 =================================================================== RCS file: /cvsroot/src/usr.bin/tail/tail.1,v retrieving revision 1.5 diff -u -r1.5 tail.1 --- tail.1 1997/10/19 23:45:11 1.5 +++ tail.1 1998/02/09 19:21:44 @@ -44,7 +44,11 @@ .Nd display the last part of a file .Sh SYNOPSIS .Nm -.Op Fl f Li | Fl r +.Oo +.Fl f | +.Fl F | +.Fl r +.Oc .Oo .Fl b Ar number | .Fl c Ar number | @@ -93,6 +97,21 @@ The .Fl f option is ignored if the standard input is a pipe, but not if it is a FIFO. +.It Fl F +The +.Fl F +option is the same as the +.Fl f +option, except that every five seconds +.Nm +will check to see if the file named on the command line has been +shortened or moved (it is considered moved if the inode or device +number changes) and, if so, it will close +the current file, open the filename given, print out the entire +contents, and continue to wait for more data to be appended. +This option is used to follow log files though rotation by +.Xr newsyslog 8 +or similar programs. .It Fl n Ar number The location is .Ar number Index: tail.c =================================================================== RCS file: /cvsroot/src/usr.bin/tail/tail.c,v retrieving revision 1.5 diff -u -r1.5 tail.c --- tail.c 1997/10/19 23:45:11 1.5 +++ tail.c 1998/02/09 19:21:44 @@ -111,8 +111,11 @@ obsolete(argv); style = NOTSET; - while ((ch = getopt(argc, argv, "b:c:fn:r")) != -1) + while ((ch = getopt(argc, argv, "Fb:c:fn:r")) != -1) switch(ch) { + case 'F': + fflag = 2; + break; case 'b': ARG(512, FBYTES, RBYTES); break; @@ -136,7 +139,7 @@ argv += optind; if (fflag && argc > 1) - err(1, "-f option only appropriate for a single file"); + err(1, "-f and -F options only appropriate for a single file"); /* * If displaying in reverse, don't permit follow option, and convert To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe hackers" in the body of the message