Hi/2.

Bruno Haible wrote:
> On native Windows, I see a test failure:
> 
> FAIL: test-fdopendir
> ====================
> 
> ../../gltests/test-fdopendir.c:76: assertion 'dup2 (fd, fd) == -1' failed
> FAIL test-fdopendir.exe (exit status: 3)
> 
> The cause of the problem is that POSIX [1] says:
>   "Upon calling closedir() the file descriptor shall be closed."
> 
> That is, the fdopendir() call has to associate the argument fd with the
> DIR object in such a way that fd gets closed when closedir() gets called
> on the DIR object, but no earlier! — see the example in [1]:
>   closedir(d); // note this implicitly closes dfd
> 
> So far, on mingw and MSVC, the DIR types (provided by mingw and gnulib,
> respectively) don't contain a field for the file descriptor. For
> implementing
>   opendir
>   readdir
>   rewinddir
>   closedir
> this was sufficient. dirfd() always returned -1 in such an implementation.
> But for fdopendir() it is not sufficient.
> 
> It's not only a test failure; it's also a file descriptor leak: For
> every pair of fdopendir/closedir calls, a file descriptor gets allocated
> and not closed.
> 
> This patch fixes it, by adding a 'fd_to_close' member.
> 
> For kLIBC, KO Myung-Hun had added a similar mechanism, by keeping a list
> of assocations between DIR objects and file descriptors. I believe
> overriding the DIR type is the more efficient way to handle this, but
> I have left the kLIBC code as it is. They can adapt the kLIBC code to
> be like the mingw code, if they like to.
> 
> [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html
> 

[...]

> diff --git a/lib/dirfd.c b/lib/dirfd.c
> index b2b1d25cdb..75b2163c35 100644
> --- a/lib/dirfd.c
> +++ b/lib/dirfd.c
> @@ -22,6 +22,10 @@
>  #include <dirent.h>
>  #include <errno.h>
>  
> +#if GNULIB_defined_DIR
> +# include "dirent-private.h"
> +#endif
> +
>  #ifdef __KLIBC__
>  # include <stdlib.h>
>  # include <io.h>
> @@ -78,11 +82,17 @@ _gl_unregister_dirp_fd (int fd)
>  int
>  dirfd (DIR *dir_p)
>  {
> +#if GNULIB_defined_DIR
> +  int fd = dir_p->fd_to_close;

dirfd() allows to take an invalid `dir_p' ?

> +  if (fd == -1)
> +    errno = EINVAL;
> +  return fd;
> +#else
>    int fd = DIR_TO_FD (dir_p);
>    if (fd == -1)
> -#ifndef __KLIBC__
> +# ifndef __KLIBC__
>      errno = ENOTSUP;
> -#else
> +# else
>      {
>        struct dirp_fd_list *dirp_fd;
>  
> @@ -92,7 +102,8 @@ dirfd (DIR *dir_p)
>  
>        errno = EINVAL;
>      }
> -#endif
> +# endif
>  
>    return fd;
> +#endif
>  }

[...]

-- 
KO Myung-Hun

Using Mozilla SeaMonkey 2.7.2
Under OS/2 Warp 4 for Korean with FixPak #15
In VirtualBox v6.1.42 on Intel Core i7-3615QM 2.30GHz with 12GB RAM

Korean OS/2 User Community : http://www.os2.kr/


Reply via email to