Browse Source

add bsd fgetln function

optimized to avoid allocation and return lines directly out of the
stream buffer whenever possible.
Rich Felker 12 năm trước cách đây
mục cha
commit
617182734c
4 tập tin đã thay đổi với 25 bổ sung1 xóa
  1. 4 0
      include/stdio.h
  2. 1 1
      src/internal/stdio_impl.h
  3. 1 0
      src/stdio/fclose.c
  4. 19 0
      src/stdio/fgetln.c

+ 4 - 0
include/stdio.h

@@ -172,6 +172,10 @@ int getw(FILE *);
 int putw(int, FILE *);
 #endif
 
+#ifdef _BSD_SOURCE
+char *fgetln(FILE *, size_t *);
+#endif
+
 #ifdef _GNU_SOURCE
 int asprintf(char **, const char *, ...);
 int vasprintf(char **, const char *, va_list);

+ 1 - 1
src/internal/stdio_impl.h

@@ -57,7 +57,7 @@ struct __FILE_s {
 	int waiters;
 	void *cookie;
 	off_t off;
-	void *dummy4;
+	char *getln_buf;
 	void *mustbezero_2;
 	unsigned char *shend;
 	off_t shlim, shcnt;

+ 1 - 0
src/stdio/fclose.c

@@ -16,6 +16,7 @@ int fclose(FILE *f)
 	r = fflush(f);
 	r |= f->close(f);
 
+	if (f->getln_buf) free(f->getln_buf);
 	if (!perm) free(f);
 	
 	return r;

+ 19 - 0
src/stdio/fgetln.c

@@ -0,0 +1,19 @@
+#include "stdio_impl.h"
+
+char *fgetln(FILE *f, size_t *plen)
+{
+	char *ret = 0, *z;
+	ssize_t l;
+	FLOCK(f);
+	ungetc(getc_unlocked(f), f);
+	if ((z=memchr(f->rpos, '\n', f->rend - f->rpos))) {
+		ret = (char *)f->rpos;
+		*plen = ++z - ret;
+		f->rpos = (void *)z;
+	} else if ((l = getline(&f->getln_buf, (size_t[]){0}, f)) > 0) {
+		*plen = l;
+		ret = f->getln_buf;
+	}
+	FUNLOCK(f);
+	return ret;
+}