mirror of
https://gitlab.freedesktop.org/libbsd/libbsd.git
synced 2025-06-10 16:12:20 +02:00
Add file buffer pool support to fgetln()
This avoids buffer overwrites during concurrent or intermixed calls to fgetln() when using more than one different stream (currently 32), which the original interface supports natively by using an internal buffer from the FILE structure. Although this workaround is rudimentary, it should cover most of the theoretically problematic cases.
This commit is contained in:
parent
1be0bdb2c9
commit
cb7bc0d85e
2
COPYING
2
COPYING
@ -66,7 +66,7 @@ for man/arc4random.3, man/tree.3 and man/getprogname.3.
|
||||
The rest of the licenses apply to code and/or man pages.
|
||||
|
||||
|
||||
Copyright © 2004-2006, 2008-2011 Guillem Jover <guillem@hadrons.org>
|
||||
Copyright © 2004-2006, 2008-2012 Guillem Jover <guillem@hadrons.org>
|
||||
Copyright © 2005 Hector Garcia Alvarez
|
||||
Copyright © 2005 Aurelien Jarno
|
||||
Copyright © 2006 Robert Millan
|
||||
|
30
src/fgetln.c
30
src/fgetln.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright © 2005 Hector Garcia Alvarez
|
||||
* Copyright © 2005, 2008, 2009, 2011 Guillem Jover <guillem@hadrons.org>
|
||||
* Copyright © 2005, 2008-2012 Guillem Jover <guillem@hadrons.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -31,21 +31,41 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_GETLINE
|
||||
struct filebuf {
|
||||
FILE *fp;
|
||||
char *buf;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
#define FILEBUF_POOL_ITEMS 32
|
||||
|
||||
static struct filebuf fb_pool[FILEBUF_POOL_ITEMS];
|
||||
static int fb_pool_cur;
|
||||
|
||||
char *
|
||||
fgetln(FILE *stream, size_t *len)
|
||||
{
|
||||
static char *line = NULL;
|
||||
static size_t line_len = 0;
|
||||
struct filebuf *fb;
|
||||
ssize_t nread;
|
||||
|
||||
nread = getline(&line, &line_len, stream);
|
||||
/* Try to diminish the possibility of several fgetln() calls being
|
||||
* used on different streams, by using a pool of buffers per file. */
|
||||
fb = &fb_pool[fb_pool_cur];
|
||||
if (fb->fp != stream && fb->fp != NULL) {
|
||||
fb_pool_cur++;
|
||||
fb_pool_cur %= FILEBUF_POOL_ITEMS;
|
||||
fb = &fb_pool[fb_pool_cur];
|
||||
}
|
||||
fb->fp = stream;
|
||||
|
||||
nread = getline(&fb->buf, &fb->len, stream);
|
||||
/* Note: the getdelim/getline API ensures nread != 0. */
|
||||
if (nread == -1) {
|
||||
*len = 0;
|
||||
return NULL;
|
||||
} else {
|
||||
*len = (size_t)nread;
|
||||
return line;
|
||||
return fb->buf;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user