diff --git a/libc/include/FILE.h b/libc/include/FILE.h index 3b505a18..594bd52c 100644 --- a/libc/include/FILE.h +++ b/libc/include/FILE.h @@ -86,6 +86,7 @@ struct FILE void (*free_func)(void* free_user, struct FILE* fp); /* Application writers shouldn't use anything beyond this point. */ pthread_mutex_t file_lock; + void (*buffer_free_indirect)(void*); struct FILE* prev; struct FILE* next; int flags; diff --git a/libc/stdio/fsetdefaultbuf_unlocked.cpp b/libc/stdio/fsetdefaultbuf_unlocked.cpp index 8598c188..bbc381d9 100644 --- a/libc/stdio/fsetdefaultbuf_unlocked.cpp +++ b/libc/stdio/fsetdefaultbuf_unlocked.cpp @@ -66,5 +66,7 @@ extern "C" int fsetdefaultbuf_unlocked(FILE* fp) // The buffer now belongs to the FILE. fp->flags |= _FILE_BUFFER_OWNED; + fp->buffer_free_indirect = free; + return 0; } diff --git a/libc/stdio/fshutdown.cpp b/libc/stdio/fshutdown.cpp index d1467ce9..caf304e0 100644 --- a/libc/stdio/fshutdown.cpp +++ b/libc/stdio/fshutdown.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2013. + Copyright(C) Jonas 'Sortie' Termansen 2013, 2014. This file is part of the Sortix C Library. @@ -34,8 +34,8 @@ extern "C" int fshutdown(FILE* fp) exact error value, for instance, as with popen/pclose. */; } ret = fp->close_func ? fp->close_func(fp->user) : ret; - if ( fp->flags & _FILE_BUFFER_OWNED ) - free(fp->buffer); + if ( fp->flags & _FILE_BUFFER_OWNED && fp->buffer_free_indirect ) + fp->buffer_free_indirect(fp->buffer); // Resetting the FILE here isn't needed in the case where fclose calls us, // but it's nice to zero it out anyway (avoiding state) data, and it's a // feature when called by freopen that wishes to reuse the FILE. It also