version 1.6, 1997/05/30 19:33:44 |
version 1.7, 1999/02/03 02:09:30 |
|
|
|
|
#include "extern.h" |
#include "extern.h" |
|
|
static void rlines __P((FILE *, long, struct stat *)); |
static int rlines __P((FILE *, long, struct stat *)); |
|
|
/* |
/* |
* forward -- display the file, from an offset, forward. |
* forward -- display the file, from an offset, forward. |
|
|
return; |
return; |
} |
} |
} else if (off == 0) { |
} else if (off == 0) { |
while (getc(fp) != EOF); |
while (getc(fp) != EOF) |
|
; |
if (ferror(fp)) { |
if (ferror(fp)) { |
ierr(); |
ierr(); |
return; |
return; |
|
|
bytes(fp, off); |
bytes(fp, off); |
break; |
break; |
case RLINES: |
case RLINES: |
if (S_ISREG(sbp->st_mode)) |
if (S_ISREG(sbp->st_mode)) { |
if (!off) { |
if (!off) { |
if (fseek(fp, 0L, SEEK_END) == -1) { |
if (fseek(fp, 0L, SEEK_END) == -1) { |
ierr(); |
ierr(); |
return; |
return; |
} |
} |
} else |
} else if (rlines(fp, off, sbp) != 0) |
rlines(fp, off, sbp); |
lines(fp, off); |
else if (off == 0) { |
} else if (off == 0) { |
while (getc(fp) != EOF); |
while (getc(fp) != EOF) |
|
; |
if (ferror(fp)) { |
if (ferror(fp)) { |
ierr(); |
ierr(); |
return; |
return; |
|
|
/* |
/* |
* rlines -- display the last offset lines of the file. |
* rlines -- display the last offset lines of the file. |
*/ |
*/ |
static void |
static int |
rlines(fp, off, sbp) |
rlines(fp, off, sbp) |
FILE *fp; |
FILE *fp; |
long off; |
long off; |
|
|
char *start; |
char *start; |
|
|
if (!(size = sbp->st_size)) |
if (!(size = sbp->st_size)) |
return; |
return (0); |
|
|
if (size > SIZE_T_MAX) { |
if (size > SIZE_T_MAX) |
errx(0, "%s: %s", fname, strerror(EFBIG)); |
return (1); |
return; |
|
} |
|
|
|
if ((start = mmap(NULL, (size_t)size, |
if ((start = mmap(NULL, (size_t)size, PROT_READ, 0, fileno(fp), |
PROT_READ, 0, fileno(fp), (off_t)0)) == (caddr_t)-1) { |
(off_t)0)) == (caddr_t)-1) |
errx(0, "%s: %s", fname, strerror(EFBIG)); |
return (1); |
return; |
|
} |
|
|
|
/* Last char is special, ignore whether newline or not. */ |
/* Last char is special, ignore whether newline or not. */ |
for (p = start + size - 1; --size;) |
for (p = start + size - 1; --size;) |
|
|
WR(p, size); |
WR(p, size); |
if (fseek(fp, (long)sbp->st_size, SEEK_SET) == -1) { |
if (fseek(fp, (long)sbp->st_size, SEEK_SET) == -1) { |
ierr(); |
ierr(); |
return; |
return (1); |
} |
} |
if (munmap(start, (size_t)sbp->st_size)) { |
if (munmap(start, (size_t)sbp->st_size)) { |
err(0, fname); |
ierr(); |
return; |
return (1); |
} |
} |
|
|
|
return (0); |
} |
} |