示例#1
0
/*
 * rlines -- display the last offset lines of the file.
 */
static void
rlines(FILE *fp, const char *fn, off_t off, struct stat *sbp)
{
	struct mapinfo map;
	off_t curoff, size;
	int i;

	if (!(size = sbp->st_size))
		return;
	map.start = NULL;
	map.fd = fileno(fp);
	map.mapoff = map.maxoff = size;

	/*
	 * Last char is special, ignore whether newline or not. Note that
	 * size == 0 is dealt with above, and size == 1 sets curoff to -1.
	 */
	curoff = size - 2;
	while (curoff >= 0) {
		if (curoff < map.mapoff && maparound(&map, curoff) != 0) {
			ierr(fn);
			return;
		}
		for (i = curoff - map.mapoff; i >= 0; i--)
			if (map.start[i] == '\n' && --off == 0)
				break;
		/* `i' is either the map offset of a '\n', or -1. */
		curoff = map.mapoff + i;
		if (i >= 0)
			break;
	}
	curoff++;
	if (mapprint(&map, curoff, size - curoff) != 0) {
		ierr(fn);
		exit(1);
	}

	/* Set the file pointer to reflect the length displayed. */
	if (fseeko(fp, sbp->st_size, SEEK_SET) == -1) {
		ierr(fn);
		return;
	}
	if (map.start != NULL && munmap(map.start, map.maplen)) {
		ierr(fn);
		return;
	}
}
示例#2
0
文件: misc.c 项目: beastix/bsdtools
/*
 * Print `len' bytes from the file associated with `mip', starting at
 * absolute file offset `startoff'. May move map window.
 */
int
mapprint(struct mapinfo *mip, off_t startoff, off_t len)
{
	int n;

	while (len > 0) {
		if (startoff < mip->mapoff || startoff >= mip->mapoff +
		    (off_t)mip->maplen) {
			if (maparound(mip, startoff) != 0)
				return (1);
		}
		n = (mip->mapoff + mip->maplen) - startoff;
		if (n > len)
			n = len;
		WR(mip->start + (startoff - mip->mapoff), n);
		startoff += n;
		len -= n;
	}
	return (0);
}
示例#3
0
/*
 * r_reg -- display a regular file in reverse order by line.
 */
static void
r_reg(FILE *fp, enum STYLE style, off_t off, struct stat *sbp)
{
	struct mapinfo map;
	off_t curoff, size, lineend;
	int i;

	if (!(size = sbp->st_size))
		return;

	map.start = NULL;
	map.mapoff = map.maxoff = size;
	map.fd = fileno(fp);

	/*
	 * Last char is special, ignore whether newline or not. Note that
	 * size == 0 is dealt with above, and size == 1 sets curoff to -1.
	 */
	curoff = size - 2;
	lineend = size;
	while (curoff >= 0) {
		if (curoff < map.mapoff ||
		    curoff >= map.mapoff + (off_t)map.maplen) {
			if (maparound(&map, curoff) != 0) {
				ierr();
				return;
			}
		}
		for (i = curoff - map.mapoff; i >= 0; i--) {
			if (style == RBYTES && --off == 0)
				break;
			if (map.start[i] == '\n')
				break;
		}
		/* `i' is either the map offset of a '\n', or -1. */
		curoff = map.mapoff + i;
		if (i < 0)
			continue;

		/* Print the line and update offsets. */
		if (mapprint(&map, curoff + 1, lineend - curoff - 1) != 0) {
			ierr();
			return;
		}
		lineend = curoff + 1;
		curoff--;

		if (style == RLINES)
			off--;

		if (off == 0 && style != REVERSE) {
			/* Avoid printing anything below. */
			curoff = 0;
			break;
		}
	}
	if (curoff < 0 && mapprint(&map, 0, lineend) != 0) {
		ierr();
		return;
	}
	if (map.start != NULL && munmap(map.start, map.maplen))
		ierr();
}