1 /* $NetBSD: read.c,v 1.17 2011/09/03 10:59:10 christos Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Edward Sze-Tyan Wang.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
38 static char sccsid
[] = "@(#)read.c 8.1 (Berkeley) 6/6/93";
40 __RCSID("$NetBSD: read.c,v 1.17 2011/09/03 10:59:10 christos Exp $");
43 #include <sys/types.h>
54 * displaybytes -- read bytes to an offset from the end and display.
56 * This is the function that reads to a byte offset from the end of the input,
57 * storing the data in a wrap-around buffer which is then displayed. If the
58 * rflag is set, the data is displayed in lines in reverse order, and this
59 * routine has the usual nastiness of trying to find the newlines. Otherwise,
60 * it is displayed from the character closest to the beginning of the input to
63 * Non-zero return means than a (non-fatal) error occurred.
66 displaybytes(FILE *fp
, off_t off
)
73 if ((sp
= p
= malloc(off
)) == NULL
)
76 for (wrap
= 0, ep
= p
+ off
; (ch
= getc(fp
)) != EOF
;) {
89 for (t
= p
- 1, len
= 0; t
>= sp
; --t
, ++len
)
90 if (*t
== '\n' && len
) {
96 for (t
= ep
- 1, len
= 0; t
>= p
; --t
, ++len
)
113 if (wrap
&& (len
= ep
- p
))
115 if ((len
= p
- sp
) != 0)
122 * displaylines -- read lines to an offset from the end and display.
124 * This is the function that reads to a line offset from the end of the input,
125 * storing the data in an array of buffers which is then displayed. If the
126 * rflag is set, the data is displayed in lines in reverse order, and this
127 * routine has the usual nastiness of trying to find the newlines. Otherwise,
128 * it is displayed from the line closest to the beginning of the input to
131 * Non-zero return means than a (non-fatal) error occurred.
134 displaylines(FILE *fp
, off_t off
)
143 int blen
, cnt
, recno
, wrap
;
147 if ((lines
= malloc(off
* sizeof(*lines
))) == NULL
)
150 memset(lines
, 0, sizeof(*lines
) * off
);
153 blen
= cnt
= recno
= wrap
= 0;
155 while ((ch
= getc(fp
)) != EOF
) {
157 if ((n
= realloc(sp
, blen
+ 1024)) == NULL
)
165 if (lines
[recno
].blen
< cnt
) {
166 if ((n
= realloc(lines
[recno
].l
,
170 lines
[recno
].blen
= cnt
+ 256;
172 memmove(lines
[recno
].l
, sp
, lines
[recno
].len
= cnt
);
175 if (++recno
== off
) {
188 lines
[recno
].len
= cnt
;
189 if (++recno
== off
) {
196 for (cnt
= recno
- 1; cnt
>= 0; --cnt
)
197 WR(lines
[cnt
].l
, lines
[cnt
].len
);
199 for (cnt
= off
- 1; cnt
>= recno
; --cnt
)
200 WR(lines
[cnt
].l
, lines
[cnt
].len
);
203 for (cnt
= recno
; cnt
< off
; ++cnt
)
204 WR(lines
[cnt
].l
, lines
[cnt
].len
);
205 for (cnt
= 0; cnt
< recno
; ++cnt
)
206 WR(lines
[cnt
].l
, lines
[cnt
].len
);