summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_tty.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_tty.cc')
-rw-r--r--winsup/cygwin/fhandler_tty.cc14
1 files changed, 14 insertions, 0 deletions
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;