From ecdee6e98ab783d321b1ffe9a10d09e19e19eb6d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 3 Mar 2006 20:19:26 +0000 Subject: [PATCH] * dir.cc (opendir): Fix indentation. * fhandler_disk_file.cc (fhandler_disk_file::opendir): Move storing fhandler in file descriptor table to some point very late in function to avoid double free'ing. Add comment to explain what happens. Add label free_mounts and don't forget to delete __DIR_mounts structure if NtOpenFile fails. --- winsup/cygwin/ChangeLog | 9 +++++++++ winsup/cygwin/dir.cc | 2 +- winsup/cygwin/fhandler_disk_file.cc | 16 +++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1c2506d78..45ca8de43 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2006-03-03 Corinna Vinschen + + * dir.cc (opendir): Fix indentation. + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Move storing + fhandler in file descriptor table to some point very late in function + to avoid double free'ing. Add comment to explain what happens. + Add label free_mounts and don't forget to delete __DIR_mounts structure + if NtOpenFile fails. + 2006-03-02 Corinna Vinschen * syscalls.cc (chroot): Disallow chroot into special directories. diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index b81b83855..c40401258 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -61,7 +61,7 @@ opendir (const char *name) if (!fh) res = NULL; else if (fh->exists ()) - res = fh->opendir (); + res = fh->opendir (); else { set_errno (ENOENT); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index dc46cbcef..0c1ed37ab 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1542,10 +1542,6 @@ fhandler_disk_file::opendir () if (fd < 0) goto free_dirent; - fd = this; - fd->nohandle (true); - dir->__d_fd = fd; - dir->__fh = this; /* FindFirstFile doesn't seem to like duplicate /'s. The dirname is generated with trailing backslash here which simplifies later usage of dirname for checking symlinks. @@ -1583,7 +1579,7 @@ fhandler_disk_file::opendir () if (!NT_SUCCESS (status)) { __seterrno_from_nt_status (status); - goto free_dirent; + goto free_mounts; } /* FileIdBothDirectoryInformation is apparently unsupported on XP @@ -1602,12 +1598,22 @@ fhandler_disk_file::opendir () } } } + /* Filling fd with `this' (aka storing this in the file descriptor table + should only happen after it's clear that opendir doesn't fail, + otherwise we end up cfree'ing the fhandler twice, once in opendir() + in dir.cc, the second time on exit. Nasty, nasty... */ + fd = this; + fd->nohandle (true); + dir->__d_fd = fd; + dir->__fh = this; res = dir; } syscall_printf ("%p = opendir (%s)", res, get_name ()); return res; +free_mounts: + delete d_mounts (dir); free_dirent: free (dir->__d_dirent); free_dirname: