summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/internal/shgetc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src/internal/shgetc.c')
-rw-r--r--libc-top-half/musl/src/internal/shgetc.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/internal/shgetc.c b/libc-top-half/musl/src/internal/shgetc.c
new file mode 100644
index 0000000..7455d2f
--- /dev/null
+++ b/libc-top-half/musl/src/internal/shgetc.c
@@ -0,0 +1,37 @@
+#include "shgetc.h"
+
+/* The shcnt field stores the number of bytes read so far, offset by
+ * the value of buf-rpos at the last function call (__shlim or __shgetc),
+ * so that between calls the inline shcnt macro can add rpos-buf to get
+ * the actual count. */
+
+void __shlim(FILE *f, off_t lim)
+{
+ f->shlim = lim;
+ f->shcnt = f->buf - f->rpos;
+ /* If lim is nonzero, rend must be a valid pointer. */
+ if (lim && f->rend - f->rpos > lim)
+ f->shend = f->rpos + lim;
+ else
+ f->shend = f->rend;
+}
+
+int __shgetc(FILE *f)
+{
+ int c;
+ off_t cnt = shcnt(f);
+ if (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {
+ f->shcnt = f->buf - f->rpos + cnt;
+ f->shend = f->rpos;
+ f->shlim = -1;
+ return EOF;
+ }
+ cnt++;
+ if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
+ f->shend = f->rpos + (f->shlim - cnt);
+ else
+ f->shend = f->rend;
+ f->shcnt = f->buf - f->rpos + cnt;
+ if (f->rpos <= f->buf) f->rpos[-1] = c;
+ return c;
+}