This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: readdir.c: d_off instead of d_reclen [PATCH]


Shaun,

The d_off field is not an offset to the next entry from the current entry; it is instead from the start of the directory: "d_off is the distance from the start of the directory to the start of the next dirent." I have seen a different definition of this field being the current directory entry as illustrated below:

Is there a problem you are solving with this change whereby the d_reclen field calculation did not give you a correct entry and if so, what system?

-- Jeff J.

DIRENT(4)                                                         DIRENT(4)
                             Standard Extension



 NAME
      dirent - file system independent directory entry

 SYNOPSIS
      #include <sys/types.h>
      #include <sys/dirent.h>

 DESCRIPTION
      Different file system types may have different directory entries.  The
      dirent structure defines a file system independent directory entry,
      which contains information common to directory entries in different
      file system types.  A set of these structures is returned by the
      getdents(2) system call.

      The dirent structure is defined below.
      struct    dirent    {
                     long           d_ino;
                     off_t               d_off;
                     unsigned short      d_reclen;
                     char           d_name[1];
                };

      The field d_ino is a number which is unique for each file in the file
      system.  The field d_off represents an offset of that directory entry
      in the actual file system directory.  The field d_name is the
      beginning of the character array giving the name of the directory
      entry.  This name is null terminated and may have at most NAME_MAX
      characters in addition to the null terminator.  This results in file
      system independent directory entries being variable-length entities.
      The value of d_reclen is the record length of this entry.  This length
      is defined to be the number of bytes between the beginning of the
      current entry and the next one, adjusted so that the next entry will
      start on a long boundary.

 FILES
      /usr/include/sys/dirent.h

 SEE ALSO
      getdents(2).

 WARNING
      The field d_off does not have a simple interpretation for some file
      system types and should not be used directly by applications.



Shaun Jackman wrote:
The getdents(2) manual page indicates d_off should be used as the
offset to the next dirent.

Cheers,
Shaun

2005-06-03 Shaun Jackman <sjackman@gmail.com>

	* newlib/libc/posix/readdir.c (readdir): Use d_off as the offset
	to the next dirent instead of d_reclen.
	* newlib/libc/posix/readdir_r.c (readdir_r): Ditto.

--- newlib/libc/posix/readdir.c- 2005-06-03 11:21:42.000000000 -0700
+++ newlib/libc/posix/readdir.c 2005-06-03 11:25:09.000000000 -0700
@@ -81,14 +81,14 @@
#endif
return NULL;
}
- if (dp->d_reclen <= 0 ||
+ if (dp->d_reclen <= 0 || dp->d_off <= 0 ||
dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) {
#ifdef HAVE_DD_LOCK
__lock_release_recursive(dirp->dd_lock);
#endif
return NULL;
}
- dirp->dd_loc += dp->d_reclen;
+ dirp->dd_loc += dp->d_off;
if (dp->d_ino == 0)
continue;
#ifdef HAVE_DD_LOCK
--- newlib/libc/posix/readdir_r.c- 2003-06-06 12:57:51.000000000 -0700
+++ newlib/libc/posix/readdir_r.c 2005-06-03 11:25:05.000000000 -0700
@@ -86,7 +86,7 @@
tmpdp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
memcpy (dp, tmpdp, sizeof(struct dirent));
- if (dp->d_reclen <= 0 ||
+ if (dp->d_reclen <= 0 || dp->d_off <= 0 ||
dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) {
#ifdef HAVE_DD_LOCK
__lock_release_recursive(dirp->dd_lock);
@@ -94,7 +94,7 @@
*dpp = NULL;
return -1;
}
- dirp->dd_loc += dp->d_reclen;
+ dirp->dd_loc += dp->d_off;
if (dp->d_ino == 0)
continue;
#ifdef HAVE_DD_LOCK


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]