xref: /third_party/musl/src/internal/shgetc.c (revision 570af302)
1570af302Sopenharmony_ci#include "shgetc.h"
2570af302Sopenharmony_ci
3570af302Sopenharmony_ci/* The shcnt field stores the number of bytes read so far, offset by
4570af302Sopenharmony_ci * the value of buf-rpos at the last function call (__shlim or __shgetc),
5570af302Sopenharmony_ci * so that between calls the inline shcnt macro can add rpos-buf to get
6570af302Sopenharmony_ci * the actual count. */
7570af302Sopenharmony_ci
8570af302Sopenharmony_civoid __shlim(FILE *f, off_t lim)
9570af302Sopenharmony_ci{
10570af302Sopenharmony_ci	f->shlim = lim;
11570af302Sopenharmony_ci	f->shcnt = f->buf - f->rpos;
12570af302Sopenharmony_ci	/* If lim is nonzero, rend must be a valid pointer. */
13570af302Sopenharmony_ci	if (lim && f->rend - f->rpos > lim)
14570af302Sopenharmony_ci		f->shend = f->rpos + lim;
15570af302Sopenharmony_ci	else
16570af302Sopenharmony_ci		f->shend = f->rend;
17570af302Sopenharmony_ci}
18570af302Sopenharmony_ci
19570af302Sopenharmony_ciint __shgetc(FILE *f)
20570af302Sopenharmony_ci{
21570af302Sopenharmony_ci	int c;
22570af302Sopenharmony_ci	off_t cnt = shcnt(f);
23570af302Sopenharmony_ci	if (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {
24570af302Sopenharmony_ci		f->shcnt = f->buf - f->rpos + cnt;
25570af302Sopenharmony_ci		f->shend = f->rpos;
26570af302Sopenharmony_ci		f->shlim = -1;
27570af302Sopenharmony_ci		return EOF;
28570af302Sopenharmony_ci	}
29570af302Sopenharmony_ci	cnt++;
30570af302Sopenharmony_ci	if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
31570af302Sopenharmony_ci		f->shend = f->rpos + (f->shlim - cnt);
32570af302Sopenharmony_ci	else
33570af302Sopenharmony_ci		f->shend = f->rend;
34570af302Sopenharmony_ci	f->shcnt = f->buf - f->rpos + cnt;
35570af302Sopenharmony_ci	if (f->rpos <= f->buf) f->rpos[-1] = c;
36570af302Sopenharmony_ci	return c;
37570af302Sopenharmony_ci}
38