summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/fhandler_tty.cc14
-rw-r--r--winsup/cygwin/path.h5
3 files changed, 26 insertions, 0 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 4986faab9..5fcd5b8c9 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_tty.cc (fhandler_tty_slave::dup): Free path_conv strings
+ to avoid memory leak. Add comment.
+ (fhandler_pty_master::dup): Ditto.
+ * path.h (path_conv::free_strings): New method.
+
2010-11-23 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (SendARP): Remove.
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 23a07d0b4..0c32d5311 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -979,6 +979,18 @@ int
fhandler_tty_slave::dup (fhandler_base *child)
{
fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
+ /* In dtable::dup_worker, the path_conv member has already been assigned
+ from "this" to "child". Part of this assigment (path_conv::operator=)
+ is to allocate memory for the strings "path" and "normalized_path from
+ cygheap. The below `child = *arch' statement will overwrite child's
+ path_conv again, this time from "*arch". By doing that, it will allocate
+ new strings from cygheap, overwriting the old pointer values. Thus, the
+ old allocated strings are lost, and we're leaking memory for each tty dup,
+ unless we free the strings here.
+ FIXME: We can't redefine path_conv::operator= so that it frees the old
+ strings. Probably it would be most helpful to copy only the required
+ members from *arch, rather than copying everything. */
+ child->pc.free_strings ();
*(fhandler_tty_slave *) child = *arch;
child->set_flags (get_flags ());
child->usecount = 0;
@@ -992,6 +1004,8 @@ int
fhandler_pty_master::dup (fhandler_base *child)
{
fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
+ /* See comment in fhandler_tty_slave::dup. */
+ child->pc.free_strings ();
*(fhandler_tty_master *) child = *arch;
child->set_flags (get_flags ());
child->usecount = 0;
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index c5b10e3c7..ef6cac44e 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -293,6 +293,11 @@ class path_conv
wide_path = NULL;
return *this;
}
+ void free_strings ()
+ {
+ cfree (modifiable_path ());
+ cfree ((char *) normalized_path);
+ }
DWORD get_devn () const {return dev.devn;}
short get_unitn () const {return dev.minor;}
DWORD file_attributes () const {return fileattr;}