forward.c revision 05d495417696d1b637b12ffc2c027668de52c7a2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * Copyright (c) 1991, 1993
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * The Regents of the University of California. All rights reserved.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * This code is derived from software contributed to Berkeley by
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * Edward Sze-Tyan Wang.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * Redistribution and use in source and binary forms, with or without
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * modification, are permitted provided that the following conditions
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * are met:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * 1. Redistributions of source code must retain the above copyright
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * notice, this list of conditions and the following disclaimer.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * 2. Redistributions in binary form must reproduce the above copyright
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * notice, this list of conditions and the following disclaimer in the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * documentation and/or other materials provided with the distribution.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * 4. Neither the name of the University nor the names of its contributors
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * may be used to endorse or promote products derived from this software
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * without specific prior written permission.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * SUCH DAMAGE.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * Solaris porting notes: the original FreeBSD version made use of the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * BSD kqueue event notification framework; this
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * was changed to use usleep()
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/param.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/mount.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/types.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/stat.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/statfs.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/statvfs.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/time.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/mman.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <sys/poll.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <port.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <err.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <errno.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <fcntl.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <limits.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <stdio.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <stdlib.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <string.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include <unistd.h>
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#include "extern.h"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic void rlines(FILE *, const char *fn, off_t, struct stat *);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic int show(file_info_t *);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic void set_events(file_info_t *files);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/* defines for inner loop actions */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#define USE_SLEEP 0
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#define ADD_EVENTS 2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaint action = USE_SLEEP;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic const file_info_t *last;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * forward -- display the file, from an offset, forward.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * There are eight separate cases for this -- regular and non-regular
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * files, by bytes or lines and from the beginning or end of the file.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * FBYTES byte offset from the beginning of the file
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * REG seek
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * NOREG read, counting bytes
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * FLINES line offset from the beginning of the file
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * REG read, counting lines
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * NOREG read, counting lines
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * RBYTES byte offset from the end of the file
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * REG seek
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * NOREG cyclically read characters into a wrap-around buffer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * RLINES
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * REG mmap the file and step back until reach the correct offset.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * NOREG cyclically read lines into a wrap-around array of buffers
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricavoid
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaforward(FILE *fp, const char *fn, enum STYLE style, off_t off, struct stat *sbp)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica{
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica int ch;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica switch (style) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case FBYTES:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (off == 0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (S_ISREG(sbp->st_mode)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (sbp->st_size < off)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica off = sbp->st_size;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (fseeko(fp, off, SEEK_SET) == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica } else while (off--)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if ((ch = getc(fp)) == EOF) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case FLINES:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (off == 0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (;;) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if ((ch = getc(fp)) == EOF) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ch == '\n' && !--off)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case RBYTES:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (S_ISREG(sbp->st_mode)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (sbp->st_size >= off &&
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica fseeko(fp, -off, SEEK_END) == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica } else if (off == 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while (getc(fp) != EOF)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica } else
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (bytes(fp, fn, off))
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case RLINES:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (S_ISREG(sbp->st_mode))
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (!off) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (fseeko(fp, (off_t)0, SEEK_END) == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica } else
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica rlines(fp, fn, off, sbp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica else if (off == 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while (getc(fp) != EOF)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica } else
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (lines(fp, fn, off))
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica default:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while ((ch = getc(fp)) != EOF)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (putchar(ch) == EOF)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica oerr();
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fflush(stdout);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * rlines -- display the last offset lines of the file.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic void
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricarlines(FILE *fp, const char *fn, off_t off, struct stat *sbp)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica{
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica struct mapinfo map;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica off_t curoff, size;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica int i;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if ((size = sbp->st_size) == 0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica map.start = NULL;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica map.fd = fileno(fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica map.mapoff = map.maxoff = size;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica /*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * Last char is special, ignore whether newline or not. Note that
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * size == 0 is dealt with above, and size == 1 sets curoff to -1.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica curoff = size - 2;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while (curoff >= 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (curoff < map.mapoff && maparound(&map, curoff) != 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (i = curoff - map.mapoff; i >= 0; i--)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (map.start[i] == '\n' && --off == 0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica /* `i' is either the map offset of a '\n', or -1. */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica curoff = map.mapoff + i;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (i >= 0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica curoff++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (mapprint(&map, curoff, size - curoff) != 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica exit(1);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica /* Set the file pointer to reflect the length displayed. */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (fseeko(fp, sbp->st_size, SEEK_SET) == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (map.start != NULL && munmap(map.start, map.maplen)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(fn);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic int
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricashow(file_info_t *file)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica{
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica int ch;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while ((ch = getc(file->fp)) != EOF) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (last != file && no_files > 1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (!qflag)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) printf("\n==> %s <==\n",
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->file_name);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica last = file;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (putchar(ch) == EOF)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica oerr();
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fflush(stdout);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ferror(file->fp)) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fclose(file->fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp = NULL;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(file->file_name);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return (0);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica clearerr(file->fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return (1);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastatic void
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaset_events(file_info_t *files)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica{
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica int i;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file_info_t *file;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (i = 0, file = files; i < no_files; i++, file++) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (! file->fp)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica continue;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fstat(fileno(file->fp), &file->st);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica/*
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * follow -- display the file, from an offset, forward.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricavoid
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricafollow(file_info_t *files, enum STYLE style, off_t off)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica{
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica int active, ev_change, i, n = -1;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica struct stat sb2;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file_info_t *file;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica /* Position each of the files */
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file = files;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica active = 0;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica n = 0;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (i = 0; i < no_files; i++, file++) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (file->fp) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica active = 1;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica n++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (no_files > 1 && !qflag)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) printf("\n==> %s <==\n",
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->file_name);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica forward(file->fp, file->file_name, style, off,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica &file->st);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (Fflag && fileno(file->fp) != STDIN_FILENO)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica n++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (!Fflag && !active)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica return;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica last = --file;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica set_events(files);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (;;) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ev_change = 0;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (Fflag) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (i = 0, file = files; i < no_files; i++, file++) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (!file->fp) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp = fopen(file->file_name, "r");
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (file->fp != NULL &&
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica fstat(fileno(file->fp), &file->st)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fclose(file->fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp = NULL;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (file->fp != NULL)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ev_change++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica continue;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (fileno(file->fp) == STDIN_FILENO)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica continue;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (stat(file->file_name, &sb2) == -1) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (errno != ENOENT)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(file->file_name);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) show(file);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) fclose(file->fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp = NULL;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ev_change++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica continue;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (sb2.st_ino != file->st.st_ino ||
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sb2.st_dev != file->st.st_dev ||
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sb2.st_nlink == 0) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) show(file);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp = freopen(file->file_name, "r",
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file->fp);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (file->fp != NULL)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) memcpy(&file->st, &sb2,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sizeof (struct stat));
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica else if (errno != ENOENT)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ierr(file->file_name);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ev_change++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for (i = 0, file = files; i < no_files; i++, file++)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (file->fp && !show(file))
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ev_change++;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if (ev_change)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica set_events(files);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica switch (action) {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case USE_SLEEP:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica (void) usleep(250000);
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica break;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica }
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica