bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dirfd on mingw


From: Bruno Haible
Subject: Re: dirfd on mingw
Date: Fri, 29 Apr 2011 00:10:49 +0200
User-agent: KMail/1.9.9

Eric Blake wrote:
> what about my idea of
> starting to associate DIR* with directory fds, for the sake of dirfd?

OK, you want to implement dirfd for native Windows? There are two issues:

1) Use a fake fd without a HANDLE, or use a real HANDLE?
2) How to associate the fd with with a DIR structure?

Ad 1): It is possible to open a HANDLE to a directory, see
  <http://msdn.microsoft.com/en-us/library/aa365258%28v=vs.85%29.aspx>
  <http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx>
  GetFileType of such a handle return FILE_TYPE_DISK.
  Since fstat() supports only handles of type FILE_TYPE_DISK, FILE_TYPE_CHAR,
  FILE_TYPE_PIPE, this means fstat() works on such a handle.
  The attached program below has been tested on Windows XP (even with an
  unprivileged user account).

  But an fd with a fake handle (INVALID_HANDLE_VALUE) is possible as well;
  it requires a bit more code in fstat() then.

  In either case, that fd is not helpful for openat() purposes.

Ad 2): You can wrap the DIR structure so that the gnulib defined DIR is a
  wrapper around the original DIR:
     struct { int fd; DIR *real_d; }
  Then opendir, readdir, closedir, rewinddir need to be overridden.

  Or you can make a mapping  DIR * -> int , through a simple association list.
  (There won't be many DIR * objects open on average.)

  For which kinds of operations would you need an  int -> DIR *  mapping?

Bruno

===============================================================================
#include <stdio.h>
#include <windows.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

int main ()
{
  HANDLE h = CreateFile ("c:\\cygwin", GENERIC_READ, 
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
FILE_FLAG_BACKUP_SEMANTICS, NULL);
  printf ("h=%p\n", h);

  int type = GetFileType (h);
  printf ("%s\n", type == FILE_TYPE_DISK ? "DISK" : type == FILE_TYPE_UNKNOWN ? 
"UNKNOWN" : "?");

  int fd = _open_osfhandle (h, O_RDWR | O_BINARY);

  struct stat statbuf;
  int ret = fstat (fd, &statbuf);
  printf ("ret = %d\n", ret);
  if (ret >= 0)
    {
      printf ("st_dev = %d\n", statbuf.st_dev);
      printf ("st_ino = %d\n", statbuf.st_ino);
      printf ("st_mode = 0%3o\n", statbuf.st_mode);
      printf ("st_nlink = %d\n", statbuf.st_nlink);
      printf ("st_uid = %d\n", statbuf.st_uid);
      printf ("st_gid = %d\n", statbuf.st_gid);
      printf ("st_rdev = %d\n", statbuf.st_rdev);
      printf ("st_size = %d\n", statbuf.st_size);
      printf ("st_atime = %s\n", ctime (&statbuf.st_atime));
      printf ("st_mtime = %s\n", ctime (&statbuf.st_mtime));
      printf ("st_ctime = %s\n", ctime (&statbuf.st_ctime));
    }

  char byte[1];
  SetLastError(0);
  ret = read (fd, byte, 1);
  printf ("read -> %d %d %d\n", ret, errno, GetLastError()); /* -> -1 EINVAL 
ERROR_INVALID_FUNCTION */

  return 0;
}
===============================================================================

-- 
In memoriam Heinz Dro├čel <http://en.wikipedia.org/wiki/Heinz_Drossel>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]