Преглед на файлове

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;
+}