فهرست منبع

add bsd fgetln function

optimized to avoid allocation and return lines directly out of the
stream buffer whenever possible.
Rich Felker 12 سال پیش
والد
کامیت
617182734c
4فایلهای تغییر یافته به همراه25 افزوده شده و 1 حذف شده
  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;
+}