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

Reply via email to