refactor stdio open file list handling, move it out of global libc struct

functions which open in-memory FILE stream variants all shared a tail
with __fdopen, adding the FILE structure to stdio's open file list.
replacing this common tail with a function call reduces code size and
duplication of logic. the list is also partially encapsulated now.

function signatures were chosen to facilitate tail call optimization
and reduce the need for additional accessor functions.

with these changes, static linked programs that do not use stdio no
longer have an open file list at all.
This commit is contained in:
Rich Felker
2015-06-16 07:11:19 +00:00
parent f22a9edaf8
commit 1b0cdc8700
12 changed files with 42 additions and 41 deletions
+1 -7
View File
@@ -54,13 +54,7 @@ FILE *__fdopen(int fd, const char *mode)
if (!libc.threaded) f->lock = -1;
/* Add new FILE to open file list */
OFLLOCK();
f->next = libc.ofl_head;
if (libc.ofl_head) libc.ofl_head->prev = f;
libc.ofl_head = f;
OFLUNLOCK();
return f;
return __ofl_add(f);
}
weak_alias(__fdopen, fdopen);
+1 -2
View File
@@ -16,8 +16,7 @@ static void close_file(FILE *f)
void __stdio_exit(void)
{
FILE *f;
OFLLOCK();
for (f=libc.ofl_head; f; f=f->next) close_file(f);
for (f=*__ofl_lock(); f; f=f->next) close_file(f);
close_file(__stdin_used);
close_file(__stdout_used);
}
+3 -3
View File
@@ -14,11 +14,11 @@ int fclose(FILE *f)
__unlist_locked_file(f);
if (!(perm = f->flags & F_PERM)) {
OFLLOCK();
FILE **head = __ofl_lock();
if (f->prev) f->prev->next = f->next;
if (f->next) f->next->prev = f->prev;
if (libc.ofl_head == f) libc.ofl_head = f->next;
OFLUNLOCK();
if (*head == f) *head = f->next;
__ofl_unlock();
}
r = fflush(f);
+2 -3
View File
@@ -35,13 +35,12 @@ int fflush(FILE *f)
r = __stdout_used ? fflush(__stdout_used) : 0;
OFLLOCK();
for (f=libc.ofl_head; f; f=f->next) {
for (f=*__ofl_lock(); f; f=f->next) {
FLOCK(f);
if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
FUNLOCK(f);
}
OFLUNLOCK();
__ofl_unlock();
return r;
}
+1 -7
View File
@@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
if (!libc.threaded) f->lock = -1;
OFLLOCK();
f->next = libc.ofl_head;
if (libc.ofl_head) libc.ofl_head->prev = f;
libc.ofl_head = f;
OFLUNLOCK();
return f;
return __ofl_add(f);
}
+16
View File
@@ -0,0 +1,16 @@
#include "stdio_impl.h"
#include "libc.h"
static FILE *ofl_head;
static volatile int ofl_lock[2];
FILE **__ofl_lock()
{
LOCK(ofl_lock);
return &ofl_head;
}
void __ofl_unlock()
{
UNLOCK(ofl_lock);
}
+11
View File
@@ -0,0 +1,11 @@
#include "stdio_impl.h"
FILE *__ofl_add(FILE *f)
{
FILE **head = __ofl_lock();
f->next = *head;
if (*head) (*head)->prev = f;
*head = f;
__ofl_unlock();
return f;
}
+1 -7
View File
@@ -79,11 +79,5 @@ FILE *open_memstream(char **bufp, size_t *sizep)
if (!libc.threaded) f->lock = -1;
OFLLOCK();
f->next = libc.ofl_head;
if (libc.ofl_head) libc.ofl_head->prev = f;
libc.ofl_head = f;
OFLUNLOCK();
return f;
return __ofl_add(f);
}
+1 -7
View File
@@ -81,11 +81,5 @@ FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
if (!libc.threaded) f->lock = -1;
OFLLOCK();
f->next = libc.ofl_head;
if (libc.ofl_head) libc.ofl_head->prev = f;
libc.ofl_head = f;
OFLUNLOCK();
return f;
return __ofl_add(f);
}