add bsd fgetln function

optimized to avoid allocation and return lines directly out of the
stream buffer whenever possible.
This commit is contained in:
Rich Felker 2012-08-11 18:10:38 -04:00
parent 2b964b010e
commit 617182734c
4 changed files with 25 additions and 1 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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
src/stdio/fgetln.c Normal file
View File

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