Hi Jinfei Fan,
On 11/01/2013 04:04 AM, Fan Jinfei wrote:
> 1. file buffer memory leak
=== modified file 'uspace/lib/c/generic/io/io.c'
--- uspace/lib/c/generic/io/io.c 2013-01-24 13:55:04 +0000
+++ uspace/lib/c/generic/io/io.c 2013-10-31 17:49:35 +0000
@@ -309,6 +309,9 @@
if (stream->fd >= 0)
rc = close(stream->fd);
+
+ if (stream->buf != NULL)
+ free(stream->buf);
list_remove(&stream->link);
The solution is probably not that straightforward as it may seem,
because setbuf() and setvbuf() may be called by applications and they
may use a static buffer. So blindly freeing the buffer would not work in
some cases.
I tried to come up with a patch that would honour this possibility. The
patch is attached to this mail. The idea is to distinguish between an
internally allocated buffer and a buffer which came from the outside.
Internally allocated buffer gets deallocated when the stream is closed,
while the externally allocated buffers are never deallocated by the library.
Comments?
Jakub
=== modified file 'uspace/lib/c/generic/io/io.c'
--- uspace/lib/c/generic/io/io.c 2013-01-24 13:55:04 +0000
+++ uspace/lib/c/generic/io/io.c 2013-11-01 20:20:11 +0000
@@ -58,6 +58,7 @@
.eof = true,
.klog = false,
.sess = NULL,
+ .bown = false,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
@@ -72,6 +73,7 @@
.eof = false,
.klog = true,
.sess = NULL,
+ .bown = false,
.btype = _IOLBF,
.buf = NULL,
.buf_size = BUFSIZ,
@@ -86,6 +88,7 @@
.eof = false,
.klog = true,
.sess = NULL,
+ .bown = false,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
@@ -183,6 +186,12 @@
/** Set stream buffer. */
void setvbuf(FILE *stream, void *buf, int mode, size_t size)
{
+ if (stream->bown) {
+ assert(stream->buf);
+ free(stream->buf);
+ }
+
+ stream->bown = false;
stream->btype = mode;
stream->buf = buf;
stream->buf_size = size;
@@ -233,6 +242,7 @@
return -1;
}
+ stream->bown = true;
stream->buf_head = stream->buf;
stream->buf_tail = stream->buf;
return 0;
@@ -269,6 +279,7 @@
stream->klog = false;
stream->sess = NULL;
stream->need_sync = false;
+ stream->bown = false;
_setvbuf(stream);
list_append(&stream->link, &files);
@@ -309,6 +320,8 @@
if (stream->fd >= 0)
rc = close(stream->fd);
+
+ setbuf(stream, NULL);
list_remove(&stream->link);
=== modified file 'uspace/lib/c/generic/private/stdio.h'
--- uspace/lib/c/generic/private/stdio.h 2012-04-02 15:52:07 +0000
+++ uspace/lib/c/generic/private/stdio.h 2013-11-01 19:29:15 +0000
@@ -63,6 +63,11 @@
* console semantics so that sync is not needed.
*/
int need_sync;
+
+ /**
+ * True if the buffer was allocated internally.
+ */
+ bool bown;
/** Buffering type */
enum _buffer_type btype;
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/listinfo/helenos-devel