Re: does anyone have a minimal opendir/readdir/closedir implementation?

From: Jamie Lokier (lk@tantalophile.demon.co.uk)
Date: Wed Sep 13 2000 - 07:34:39 EST


Felix von Leitner wrote:
> The kernel interface seems to be:
>
> * supply an O_DIRECTORY flag to open()

O_DIRECTORY means "refuse to open if not a directory".
Old kernels ignore the flag.

So Glibc then calls fstat() to check it's really a directory.
(opendir() is required to fail on non-directories).

Actually Glibc does 4 system calls: open, fstat64, fstat (when fstat64
fails), fcntl (...FD_CLOEXEC...).

> * a getdents system call

> You don't read on the fd in readdir, you call getdents.
> getdents reads n struct dirents. You can't say how many you want, you
> can only limit the bytes it copies. Oh, and that's a kernel struct
> dirent, which is subtly different from the glibc one (it does not
> contain the d_type field).
>
> So a "natural" approach would be to have opendir call getdents on a
> "big" buffer to get all the records and then have readdir return each
> one. But... how do I know how much space to reserve? lseek can find
> out the file size, but directories under /proc have a size of 0.
>
> glibc seems to handle this by defining an elaborate buffer data structure.

The kernel getdents interface is almost identical to Glibc's
__getdirentries interface:

  0 => finished.
  -1/EINVAL => make your buffer bigger because it's not big enough
  for 1 large entry.
  N => read N bytes

The only significant difference is that it uses a different structure.

Glibc looks complicated because it translates between the structures, so
it must (a) pass a smaller buffer size to the kernel; (b) copy the
smaller returned structures to Glibc API structures.

If your dietlibc doesn't have to be binary compatible with Glibc, you
can just use the kernel-format structure as your API.

Btw, the kernel recently added getdents64, which uses the same structure
as Glibc API. You could just use that if you're willing to require
current 2.4 kernels.

-- Jamie
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Sep 15 2000 - 21:00:20 EST