summaryrefslogtreecommitdiff
path: root/src/stdio/fgets.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdio/fgets.c')
-rw-r--r--src/stdio/fgets.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/stdio/fgets.c b/src/stdio/fgets.c
new file mode 100644
index 00000000..7939303e
--- /dev/null
+++ b/src/stdio/fgets.c
@@ -0,0 +1,34 @@
+#include "stdio_impl.h"
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+char *fgets(char *s, int n, FILE *f)
+{
+ char *p = s;
+ unsigned char *z;
+ size_t k;
+
+ if (!n--) return 0;
+
+ FLOCK(f);
+
+ while (n && !feof(f)) {
+ z = memchr(f->rpos, '\n', f->rend - f->rpos);
+ k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+ k = MIN(k, n);
+ memcpy(p, f->rpos, k);
+ f->rpos += k;
+ p += k;
+ n -= k;
+ if (z) break;
+ __underflow(f);
+ }
+ *p = 0;
+ if (ferror(f)) p = s;
+
+ FUNLOCK(f);
+
+ return (p == s) ? 0 : s;
+}
+
+weak_alias(fgets, fgets_unlocked);