[01/10] linux: Move posix dir implementations to Linux

Message ID 20200417132209.22065-1-adhemerval.zanella@linaro.org
State Superseded
Headers
Series [01/10] linux: Move posix dir implementations to Linux |

Commit Message

Adhemerval Zanella April 17, 2020, 1:22 p.m. UTC
  This generic implementation already expects a getdents API which
is Linux specific.  It also allows simplify it by assuming
_DIRENT_HAVE_D_RECLEN and _DIRENT_HAVE_D_OFF support.

The readdir are also expanded on each required implementation,
futher fixes and improvements will make parametrize the
implementation more complex.

Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build
for all affected ABIs.
---
 sysdeps/posix/readdir.c                       | 127 ------------
 sysdeps/posix/readdir_r.c                     | 159 --------------
 sysdeps/unix/sysv/linux/alpha/bits/dirent.h   |   6 +-
 sysdeps/unix/sysv/linux/bits/dirent.h         |   6 +-
 sysdeps/{posix => unix/sysv/linux}/closedir.c |   0
 sysdeps/{posix => unix/sysv/linux}/dirfd.c    |   0
 .../{posix => unix/sysv/linux}/dirstream.h    |   0
 .../{posix => unix/sysv/linux}/fdopendir.c    |   0
 sysdeps/{posix => unix/sysv/linux}/opendir.c  |   0
 sysdeps/unix/sysv/linux/readdir.c             |  65 +++++-
 sysdeps/unix/sysv/linux/readdir64.c           | 131 +++++++++++-
 sysdeps/unix/sysv/linux/readdir64_r.c         | 194 +++++++++++++++++-
 sysdeps/unix/sysv/linux/readdir_r.c           |  95 ++++++++-
 .../{posix => unix/sysv/linux}/rewinddir.c    |   0
 sysdeps/{posix => unix/sysv/linux}/seekdir.c  |   0
 sysdeps/{posix => unix/sysv/linux}/telldir.c  |   0
 16 files changed, 468 insertions(+), 315 deletions(-)
 delete mode 100644 sysdeps/posix/readdir.c
 delete mode 100644 sysdeps/posix/readdir_r.c
 rename sysdeps/{posix => unix/sysv/linux}/closedir.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/dirfd.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/dirstream.h (100%)
 rename sysdeps/{posix => unix/sysv/linux}/fdopendir.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/opendir.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/rewinddir.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/seekdir.c (100%)
 rename sysdeps/{posix => unix/sysv/linux}/telldir.c (100%)
  

Comments

Andreas Schwab April 20, 2020, 2:53 p.m. UTC | #1
On Apr 17 2020, Adhemerval Zanella via Libc-alpha wrote:

> This generic implementation already expects a getdents API which
> is Linux specific.

It is also provided by FreeBSD, though.

> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> index 953d590cff..649b6bcb78 100644
> --- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> +++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> @@ -47,9 +47,9 @@ struct dirent64
>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>  
>  #undef  _DIRENT_HAVE_D_NAMLEN
> -#define _DIRENT_HAVE_D_RECLEN
> -#define _DIRENT_HAVE_D_OFF
> -#define _DIRENT_HAVE_D_TYPE
> +#define _DIRENT_HAVE_D_RECLEN		1
> +#define _DIRENT_HAVE_D_OFF		1
> +#define _DIRENT_HAVE_D_TYPE		1
>  
>  /* Inform libc code that these two types are effectively identical.  */
>  #define _DIRENT_MATCHES_DIRENT64	1
> diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h
> index 9e4df8a58b..82c38d9ef8 100644
> --- a/sysdeps/unix/sysv/linux/bits/dirent.h
> +++ b/sysdeps/unix/sysv/linux/bits/dirent.h
> @@ -47,9 +47,9 @@ struct dirent64
>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>  
>  #undef  _DIRENT_HAVE_D_NAMLEN
> -#define _DIRENT_HAVE_D_RECLEN
> -#define _DIRENT_HAVE_D_OFF
> -#define _DIRENT_HAVE_D_TYPE
> +#define _DIRENT_HAVE_D_RECLEN		1
> +#define _DIRENT_HAVE_D_OFF		1
> +#define _DIRENT_HAVE_D_TYPE		1

That part does not fit here.  Also, all occurences still use #ifdef.

Andreas.
  
Florian Weimer April 21, 2020, 10:15 a.m. UTC | #2
* Andreas Schwab:

> On Apr 17 2020, Adhemerval Zanella via Libc-alpha wrote:
>
>> This generic implementation already expects a getdents API which
>> is Linux specific.
>
> It is also provided by FreeBSD, though.

Do you think the commit message should be updated to reflect that?
Or do you object to moving the implementation at all?

(There is still an out-of-tree FreeBSD port.)
  
Adhemerval Zanella April 21, 2020, 11:51 a.m. UTC | #3
On 20/04/2020 11:53, Andreas Schwab wrote:
> On Apr 17 2020, Adhemerval Zanella via Libc-alpha wrote:
> 
>> This generic implementation already expects a getdents API which
>> is Linux specific.
> 
> It is also provided by FreeBSD, though.

Either getdirentries or getdents could be used (on FreeBSD getdents
is implemented on top of getdirentries). Another reason to move the
implementation to be Linux only is further fixes in this patch set
would make the generic implementation somewhat more complex (since 
Linux dirstream would deviate from generic).

> 
>> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
>> index 953d590cff..649b6bcb78 100644
>> --- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
>> +++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
>> @@ -47,9 +47,9 @@ struct dirent64
>>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>>  
>>  #undef  _DIRENT_HAVE_D_NAMLEN
>> -#define _DIRENT_HAVE_D_RECLEN
>> -#define _DIRENT_HAVE_D_OFF
>> -#define _DIRENT_HAVE_D_TYPE
>> +#define _DIRENT_HAVE_D_RECLEN		1
>> +#define _DIRENT_HAVE_D_OFF		1
>> +#define _DIRENT_HAVE_D_TYPE		1
>>  
>>  /* Inform libc code that these two types are effectively identical.  */
>>  #define _DIRENT_MATCHES_DIRENT64	1
>> diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h
>> index 9e4df8a58b..82c38d9ef8 100644
>> --- a/sysdeps/unix/sysv/linux/bits/dirent.h
>> +++ b/sysdeps/unix/sysv/linux/bits/dirent.h
>> @@ -47,9 +47,9 @@ struct dirent64
>>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>>  
>>  #undef  _DIRENT_HAVE_D_NAMLEN
>> -#define _DIRENT_HAVE_D_RECLEN
>> -#define _DIRENT_HAVE_D_OFF
>> -#define _DIRENT_HAVE_D_TYPE
>> +#define _DIRENT_HAVE_D_RECLEN		1
>> +#define _DIRENT_HAVE_D_OFF		1
>> +#define _DIRENT_HAVE_D_TYPE		1
> 
> That part does not fit here.  Also, all occurences still use #ifdef.

Ack, I have removed it.
  
Adhemerval Zanella May 27, 2020, 4:35 p.m. UTC | #4
Ping (with Andreas remarks regard DIRENT_HAVE_ change removed).

On 17/04/2020 10:22, Adhemerval Zanella wrote:
> This generic implementation already expects a getdents API which
> is Linux specific.  It also allows simplify it by assuming
> _DIRENT_HAVE_D_RECLEN and _DIRENT_HAVE_D_OFF support.
> 
> The readdir are also expanded on each required implementation,
> futher fixes and improvements will make parametrize the
> implementation more complex.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build
> for all affected ABIs.
> ---
>  sysdeps/posix/readdir.c                       | 127 ------------
>  sysdeps/posix/readdir_r.c                     | 159 --------------
>  sysdeps/unix/sysv/linux/alpha/bits/dirent.h   |   6 +-
>  sysdeps/unix/sysv/linux/bits/dirent.h         |   6 +-
>  sysdeps/{posix => unix/sysv/linux}/closedir.c |   0
>  sysdeps/{posix => unix/sysv/linux}/dirfd.c    |   0
>  .../{posix => unix/sysv/linux}/dirstream.h    |   0
>  .../{posix => unix/sysv/linux}/fdopendir.c    |   0
>  sysdeps/{posix => unix/sysv/linux}/opendir.c  |   0
>  sysdeps/unix/sysv/linux/readdir.c             |  65 +++++-
>  sysdeps/unix/sysv/linux/readdir64.c           | 131 +++++++++++-
>  sysdeps/unix/sysv/linux/readdir64_r.c         | 194 +++++++++++++++++-
>  sysdeps/unix/sysv/linux/readdir_r.c           |  95 ++++++++-
>  .../{posix => unix/sysv/linux}/rewinddir.c    |   0
>  sysdeps/{posix => unix/sysv/linux}/seekdir.c  |   0
>  sysdeps/{posix => unix/sysv/linux}/telldir.c  |   0
>  16 files changed, 468 insertions(+), 315 deletions(-)
>  delete mode 100644 sysdeps/posix/readdir.c
>  delete mode 100644 sysdeps/posix/readdir_r.c
>  rename sysdeps/{posix => unix/sysv/linux}/closedir.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/dirfd.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/dirstream.h (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/fdopendir.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/opendir.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/rewinddir.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/seekdir.c (100%)
>  rename sysdeps/{posix => unix/sysv/linux}/telldir.c (100%)
> 
> diff --git a/sysdeps/posix/readdir.c b/sysdeps/posix/readdir.c
> deleted file mode 100644
> index b36278b5f4..0000000000
> --- a/sysdeps/posix/readdir.c
> +++ /dev/null
> @@ -1,127 +0,0 @@
> -/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <limits.h>
> -#include <stddef.h>
> -#include <string.h>
> -#include <dirent.h>
> -#include <unistd.h>
> -#include <sys/types.h>
> -#include <assert.h>
> -
> -#include <dirstream.h>
> -
> -#ifndef __READDIR
> -# define __READDIR __readdir
> -# define __GETDENTS __getdents
> -# define DIRENT_TYPE struct dirent
> -# define __READDIR_ALIAS
> -#endif
> -
> -/* Read a directory entry from DIRP.  */
> -DIRENT_TYPE *
> -__READDIR (DIR *dirp)
> -{
> -  DIRENT_TYPE *dp;
> -  int saved_errno = errno;
> -
> -#if IS_IN (libc)
> -  __libc_lock_lock (dirp->lock);
> -#endif
> -
> -  do
> -    {
> -      size_t reclen;
> -
> -      if (dirp->offset >= dirp->size)
> -	{
> -	  /* We've emptied out our buffer.  Refill it.  */
> -
> -	  size_t maxread;
> -	  ssize_t bytes;
> -
> -#ifndef _DIRENT_HAVE_D_RECLEN
> -	  /* Fixed-size struct; must read one at a time (see below).  */
> -	  maxread = sizeof *dp;
> -#else
> -	  maxread = dirp->allocation;
> -#endif
> -
> -	  bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
> -	  if (bytes <= 0)
> -	    {
> -	      /* On some systems getdents fails with ENOENT when the
> -		 open directory has been rmdir'd already.  POSIX.1
> -		 requires that we treat this condition like normal EOF.  */
> -	      if (bytes < 0 && errno == ENOENT)
> -		bytes = 0;
> -
> -	      /* Don't modifiy errno when reaching EOF.  */
> -	      if (bytes == 0)
> -		__set_errno (saved_errno);
> -	      dp = NULL;
> -	      break;
> -	    }
> -	  dirp->size = (size_t) bytes;
> -
> -	  /* Reset the offset into the buffer.  */
> -	  dirp->offset = 0;
> -	}
> -
> -      dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
> -
> -#ifdef _DIRENT_HAVE_D_RECLEN
> -      reclen = dp->d_reclen;
> -#else
> -      /* The only version of `struct dirent*' that lacks `d_reclen'
> -	 is fixed-size.  */
> -      assert (sizeof dp->d_name > 1);
> -      reclen = sizeof *dp;
> -      /* The name is not terminated if it is the largest possible size.
> -	 Clobber the following byte to ensure proper null termination.  We
> -	 read jst one entry at a time above so we know that byte will not
> -	 be used later.  */
> -      dp->d_name[sizeof dp->d_name] = '\0';
> -#endif
> -
> -      dirp->offset += reclen;
> -
> -#ifdef _DIRENT_HAVE_D_OFF
> -      dirp->filepos = dp->d_off;
> -#else
> -      dirp->filepos += reclen;
> -#endif
> -
> -      /* Skip deleted files.  */
> -    } while (dp->d_ino == 0);
> -
> -#if IS_IN (libc)
> -  __libc_lock_unlock (dirp->lock);
> -#endif
> -
> -  return dp;
> -}
> -
> -#ifdef __READDIR_ALIAS
> -weak_alias (__readdir, readdir)
> -#endif
> -
> -#undef __READDIR
> -#undef __GETDENTS
> -#undef DIRENT_TYPE
> -#undef __READDIR_ALIAS
> diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c
> deleted file mode 100644
> index 9079abc2ff..0000000000
> --- a/sysdeps/posix/readdir_r.c
> +++ /dev/null
> @@ -1,159 +0,0 @@
> -/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <limits.h>
> -#include <stddef.h>
> -#include <string.h>
> -#include <dirent.h>
> -#include <unistd.h>
> -#include <sys/types.h>
> -#include <assert.h>
> -
> -#include <dirstream.h>
> -
> -#ifndef __READDIR_R
> -# define __READDIR_R __readdir_r
> -# define __GETDENTS __getdents
> -# define DIRENT_TYPE struct dirent
> -# define __READDIR_R_ALIAS
> -#endif
> -
> -/* Read a directory entry from DIRP.  */
> -int
> -__READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
> -{
> -  DIRENT_TYPE *dp;
> -  size_t reclen;
> -  const int saved_errno = errno;
> -  int ret;
> -
> -  __libc_lock_lock (dirp->lock);
> -
> -  do
> -    {
> -      if (dirp->offset >= dirp->size)
> -	{
> -	  /* We've emptied out our buffer.  Refill it.  */
> -
> -	  size_t maxread;
> -	  ssize_t bytes;
> -
> -#ifndef _DIRENT_HAVE_D_RECLEN
> -	  /* Fixed-size struct; must read one at a time (see below).  */
> -	  maxread = sizeof *dp;
> -#else
> -	  maxread = dirp->allocation;
> -#endif
> -
> -	  bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
> -	  if (bytes <= 0)
> -	    {
> -	      /* On some systems getdents fails with ENOENT when the
> -		 open directory has been rmdir'd already.  POSIX.1
> -		 requires that we treat this condition like normal EOF.  */
> -	      if (bytes < 0 && errno == ENOENT)
> -		{
> -		  bytes = 0;
> -		  __set_errno (saved_errno);
> -		}
> -	      if (bytes < 0)
> -		dirp->errcode = errno;
> -
> -	      dp = NULL;
> -	      break;
> -	    }
> -	  dirp->size = (size_t) bytes;
> -
> -	  /* Reset the offset into the buffer.  */
> -	  dirp->offset = 0;
> -	}
> -
> -      dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
> -
> -#ifdef _DIRENT_HAVE_D_RECLEN
> -      reclen = dp->d_reclen;
> -#else
> -      /* The only version of `struct dirent*' that lacks `d_reclen'
> -	 is fixed-size.  */
> -      assert (sizeof dp->d_name > 1);
> -      reclen = sizeof *dp;
> -      /* The name is not terminated if it is the largest possible size.
> -	 Clobber the following byte to ensure proper null termination.  We
> -	 read just one entry at a time above so we know that byte will not
> -	 be used later.  */
> -      dp->d_name[sizeof dp->d_name] = '\0';
> -#endif
> -
> -      dirp->offset += reclen;
> -
> -#ifdef _DIRENT_HAVE_D_OFF
> -      dirp->filepos = dp->d_off;
> -#else
> -      dirp->filepos += reclen;
> -#endif
> -
> -#ifdef NAME_MAX
> -      if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
> -	{
> -	  /* The record is very long.  It could still fit into the
> -	     caller-supplied buffer if we can skip padding at the
> -	     end.  */
> -	  size_t namelen = _D_EXACT_NAMLEN (dp);
> -	  if (namelen <= NAME_MAX)
> -	    reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
> -	  else
> -	    {
> -	      /* The name is too long.  Ignore this file.  */
> -	      dirp->errcode = ENAMETOOLONG;
> -	      dp->d_ino = 0;
> -	      continue;
> -	    }
> -	}
> -#endif
> -
> -      /* Skip deleted and ignored files.  */
> -    }
> -  while (dp->d_ino == 0);
> -
> -  if (dp != NULL)
> -    {
> -      *result = memcpy (entry, dp, reclen);
> -#ifdef _DIRENT_HAVE_D_RECLEN
> -      entry->d_reclen = reclen;
> -#endif
> -      ret = 0;
> -    }
> -  else
> -    {
> -      *result = NULL;
> -      ret = dirp->errcode;
> -    }
> -
> -  __libc_lock_unlock (dirp->lock);
> -
> -  return ret;
> -}
> -
> -#ifdef __READDIR_R_ALIAS
> -weak_alias (__readdir_r, readdir_r)
> -#endif
> -
> -#undef __READDIR_R
> -#undef __GETDENTS
> -#undef DIRENT_TYPE
> -#undef __READDIR_R_ALIAS
> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> index 953d590cff..649b6bcb78 100644
> --- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> +++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
> @@ -47,9 +47,9 @@ struct dirent64
>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>  
>  #undef  _DIRENT_HAVE_D_NAMLEN
> -#define _DIRENT_HAVE_D_RECLEN
> -#define _DIRENT_HAVE_D_OFF
> -#define _DIRENT_HAVE_D_TYPE
> +#define _DIRENT_HAVE_D_RECLEN		1
> +#define _DIRENT_HAVE_D_OFF		1
> +#define _DIRENT_HAVE_D_TYPE		1
>  
>  /* Inform libc code that these two types are effectively identical.  */
>  #define _DIRENT_MATCHES_DIRENT64	1
> diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h
> index 9e4df8a58b..82c38d9ef8 100644
> --- a/sysdeps/unix/sysv/linux/bits/dirent.h
> +++ b/sysdeps/unix/sysv/linux/bits/dirent.h
> @@ -47,9 +47,9 @@ struct dirent64
>  #define d_fileno	d_ino	/* Backwards compatibility.  */
>  
>  #undef  _DIRENT_HAVE_D_NAMLEN
> -#define _DIRENT_HAVE_D_RECLEN
> -#define _DIRENT_HAVE_D_OFF
> -#define _DIRENT_HAVE_D_TYPE
> +#define _DIRENT_HAVE_D_RECLEN		1
> +#define _DIRENT_HAVE_D_OFF		1
> +#define _DIRENT_HAVE_D_TYPE		1
>  
>  #if defined __OFF_T_MATCHES_OFF64_T && defined __INO_T_MATCHES_INO64_T
>  /* Inform libc code that these two types are effectively identical.  */
> diff --git a/sysdeps/posix/closedir.c b/sysdeps/unix/sysv/linux/closedir.c
> similarity index 100%
> rename from sysdeps/posix/closedir.c
> rename to sysdeps/unix/sysv/linux/closedir.c
> diff --git a/sysdeps/posix/dirfd.c b/sysdeps/unix/sysv/linux/dirfd.c
> similarity index 100%
> rename from sysdeps/posix/dirfd.c
> rename to sysdeps/unix/sysv/linux/dirfd.c
> diff --git a/sysdeps/posix/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
> similarity index 100%
> rename from sysdeps/posix/dirstream.h
> rename to sysdeps/unix/sysv/linux/dirstream.h
> diff --git a/sysdeps/posix/fdopendir.c b/sysdeps/unix/sysv/linux/fdopendir.c
> similarity index 100%
> rename from sysdeps/posix/fdopendir.c
> rename to sysdeps/unix/sysv/linux/fdopendir.c
> diff --git a/sysdeps/posix/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
> similarity index 100%
> rename from sysdeps/posix/opendir.c
> rename to sysdeps/unix/sysv/linux/opendir.c
> diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
> index df7a92aa78..2e03e66e69 100644
> --- a/sysdeps/unix/sysv/linux/readdir.c
> +++ b/sysdeps/unix/sysv/linux/readdir.c
> @@ -19,5 +19,68 @@
>  #include <dirent.h>
>  
>  #if !_DIRENT_MATCHES_DIRENT64
> -# include <sysdeps/posix/readdir.c>
> +#include <dirstream.h>
> +
> +/* Read a directory entry from DIRP.  */
> +struct dirent *
> +__readdir (DIR *dirp)
> +{
> +  struct dirent *dp;
> +  int saved_errno = errno;
> +
> +#if IS_IN (libc)
> +  __libc_lock_lock (dirp->lock);
> +#endif
> +
> +  do
> +    {
> +      size_t reclen;
> +
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  bytes = __getdents (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		bytes = 0;
> +
> +	      /* Don't modifiy errno when reaching EOF.  */
> +	      if (bytes == 0)
> +		__set_errno (saved_errno);
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
> +
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct dirent *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      /* Skip deleted files.  */
> +    } while (dp->d_ino == 0);
> +
> +#if IS_IN (libc)
> +  __libc_lock_unlock (dirp->lock);
> +#endif
> +
> +  return dp;
> +}
> +weak_alias (__readdir, readdir)
> +
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
> index 7d4b0001b3..e4d56cb2ae 100644
> --- a/sysdeps/unix/sysv/linux/readdir64.c
> +++ b/sysdeps/unix/sysv/linux/readdir64.c
> @@ -23,17 +23,71 @@
>  #define readdir   __no_readdir_decl
>  #define __readdir __no___readdir_decl
>  #include <dirent.h>
> +#undef __readdir
> +#undef readdir
>  
> -#define __READDIR   __readdir64
> -#define __GETDENTS  __getdents64
> -#define DIRENT_TYPE struct dirent64
> +/* Read a directory entry from DIRP.  */
> +struct dirent64 *
> +__readdir64 (DIR *dirp)
> +{
> +  struct dirent64 *dp;
> +  int saved_errno = errno;
>  
> -#include <sysdeps/posix/readdir.c>
> +#if IS_IN (libc)
> +  __libc_lock_lock (dirp->lock);
> +#endif
>  
> -#undef __readdir
> -#undef readdir
> +  do
> +    {
> +      size_t reclen;
> +
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		bytes = 0;
> +
> +	      /* Don't modifiy errno when reaching EOF.  */
> +	      if (bytes == 0)
> +		__set_errno (saved_errno);
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
>  
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct dirent64 *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      /* Skip deleted files.  */
> +    } while (dp->d_ino == 0);
> +
> +#if IS_IN (libc)
> +  __libc_lock_unlock (dirp->lock);
> +#endif
> +
> +  return dp;
> +}
>  libc_hidden_def (__readdir64)
> +
>  #if _DIRENT_MATCHES_DIRENT64
>  strong_alias (__readdir64, __readdir)
>  weak_alias (__readdir64, readdir64)
> @@ -45,10 +99,67 @@ weak_alias (__readdir64, readdir)
>  versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
>  # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
>  #  include <olddirent.h>
> -#  define __READDIR   attribute_compat_text_section __old_readdir64
> -#  define __GETDENTS  __old_getdents64
> -#  define DIRENT_TYPE struct __old_dirent64
> -#  include <sysdeps/posix/readdir.c>
> +
> +attribute_compat_text_section
> +struct __old_dirent64 *
> +__old_readdir64 (DIR *dirp)
> +{
> +  struct __old_dirent64 *dp;
> +  int saved_errno = errno;
> +
> +#if IS_IN (libc)
> +  __libc_lock_lock (dirp->lock);
> +#endif
> +
> +  do
> +    {
> +      size_t reclen;
> +
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		bytes = 0;
> +
> +	      /* Don't modifiy errno when reaching EOF.  */
> +	      if (bytes == 0)
> +		__set_errno (saved_errno);
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
> +
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      /* Skip deleted files.  */
> +    } while (dp->d_ino == 0);
> +
> +#if IS_IN (libc)
> +  __libc_lock_unlock (dirp->lock);
> +#endif
> +
> +  return dp;
> +}
>  libc_hidden_def (__old_readdir64)
>  compat_symbol (libc, __old_readdir64, readdir64, GLIBC_2_1);
>  # endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)  */
> diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
> index 6d589f36f5..c587787417 100644
> --- a/sysdeps/unix/sysv/linux/readdir64_r.c
> +++ b/sysdeps/unix/sysv/linux/readdir64_r.c
> @@ -23,15 +23,100 @@
>  #define readdir_r   __no_readdir_r_decl
>  #define __readdir_r __no___readdir_r_decl
>  #include <dirent.h>
> +#undef __readdir_r
> +#undef readdir_r
>  
> -#define __READDIR_R __readdir64_r
> -#define __GETDENTS  __getdents64
> -#define DIRENT_TYPE struct dirent64
> +/* Read a directory entry from DIRP.  */
> +int
> +__readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
> +{
> +  struct dirent64 *dp;
> +  size_t reclen;
> +  const int saved_errno = errno;
> +  int ret;
>  
> -#include <sysdeps/posix/readdir_r.c>
> +  __libc_lock_lock (dirp->lock);
> +
> +  do
> +    {
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  maxread = dirp->allocation;
> +
> +	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		{
> +		  bytes = 0;
> +		  __set_errno (saved_errno);
> +		}
> +	      if (bytes < 0)
> +		dirp->errcode = errno;
> +
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
> +
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct dirent64 *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      if (reclen > offsetof (struct dirent64, d_name) + NAME_MAX + 1)
> +	{
> +	  /* The record is very long.  It could still fit into the
> +	     caller-supplied buffer if we can skip padding at the
> +	     end.  */
> +	  size_t namelen = _D_EXACT_NAMLEN (dp);
> +	  if (namelen <= NAME_MAX)
> +	    reclen = offsetof (struct dirent64, d_name) + namelen + 1;
> +	  else
> +	    {
> +	      /* The name is too long.  Ignore this file.  */
> +	      dirp->errcode = ENAMETOOLONG;
> +	      dp->d_ino = 0;
> +	      continue;
> +	    }
> +	}
> +
> +      /* Skip deleted and ignored files.  */
> +    }
> +  while (dp->d_ino == 0);
> +
> +  if (dp != NULL)
> +    {
> +      *result = memcpy (entry, dp, reclen);
> +      entry->d_reclen = reclen;
> +      ret = 0;
> +    }
> +  else
> +    {
> +      *result = NULL;
> +      ret = dirp->errcode;
> +    }
> +
> +  __libc_lock_unlock (dirp->lock);
> +
> +  return ret;
> +}
>  
> -#undef __readdir_r
> -#undef readdir_r
>  
>  #if _DIRENT_MATCHES_DIRENT64
>  strong_alias (__readdir64_r, __readdir_r)
> @@ -44,10 +129,99 @@ weak_alias (__readdir64_r, readdir64_r)
>  versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
>  # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
>  #  include <olddirent.h>
> -#  define __READDIR_R attribute_compat_text_section __old_readdir64_r
> -#  define __GETDENTS  __old_getdents64
> -#  define DIRENT_TYPE struct __old_dirent64
> -#  include <sysdeps/posix/readdir_r.c>
> +
> +int
> +attribute_compat_text_section
> +__old_readdir64_r (DIR *dirp, struct __old_dirent64 *entry,
> +		   struct __old_dirent64 **result)
> +{
> +  struct __old_dirent64 *dp;
> +  size_t reclen;
> +  const int saved_errno = errno;
> +  int ret;
> +
> +  __libc_lock_lock (dirp->lock);
> +
> +  do
> +    {
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  maxread = dirp->allocation;
> +
> +	  bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		{
> +		  bytes = 0;
> +		  __set_errno (saved_errno);
> +		}
> +	      if (bytes < 0)
> +		dirp->errcode = errno;
> +
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
> +
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      if (reclen > offsetof (struct __old_dirent64, d_name) + NAME_MAX + 1)
> +	{
> +	  /* The record is very long.  It could still fit into the
> +	     caller-supplied buffer if we can skip padding at the
> +	     end.  */
> +	  size_t namelen = _D_EXACT_NAMLEN (dp);
> +	  if (namelen <= NAME_MAX)
> +	    reclen = offsetof (struct __old_dirent64, d_name) + namelen + 1;
> +	  else
> +	    {
> +	      /* The name is too long.  Ignore this file.  */
> +	      dirp->errcode = ENAMETOOLONG;
> +	      dp->d_ino = 0;
> +	      continue;
> +	    }
> +	}
> +
> +      /* Skip deleted and ignored files.  */
> +    }
> +  while (dp->d_ino == 0);
> +
> +  if (dp != NULL)
> +    {
> +      *result = memcpy (entry, dp, reclen);
> +      entry->d_reclen = reclen;
> +      ret = 0;
> +    }
> +  else
> +    {
> +      *result = NULL;
> +      ret = dirp->errcode;
> +    }
> +
> +  __libc_lock_unlock (dirp->lock);
> +
> +  return ret;
> +}
> +
>  compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
>  # endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)  */
>  #endif /* _DIRENT_MATCHES_DIRENT64  */
> diff --git a/sysdeps/unix/sysv/linux/readdir_r.c b/sysdeps/unix/sysv/linux/readdir_r.c
> index 30f237dbcc..0069041394 100644
> --- a/sysdeps/unix/sysv/linux/readdir_r.c
> +++ b/sysdeps/unix/sysv/linux/readdir_r.c
> @@ -19,5 +19,96 @@
>  #include <dirent.h>
>  
>  #if !_DIRENT_MATCHES_DIRENT64
> -# include <sysdeps/posix/readdir_r.c>
> -#endif
> +/* Read a directory entry from DIRP.  */
> +int
> +__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
> +{
> +  struct dirent *dp;
> +  size_t reclen;
> +  const int saved_errno = errno;
> +  int ret;
> +
> +  __libc_lock_lock (dirp->lock);
> +
> +  do
> +    {
> +      if (dirp->offset >= dirp->size)
> +	{
> +	  /* We've emptied out our buffer.  Refill it.  */
> +
> +	  size_t maxread = dirp->allocation;
> +	  ssize_t bytes;
> +
> +	  maxread = dirp->allocation;
> +
> +	  bytes = __getdents (dirp->fd, dirp->data, maxread);
> +	  if (bytes <= 0)
> +	    {
> +	      /* On some systems getdents fails with ENOENT when the
> +		 open directory has been rmdir'd already.  POSIX.1
> +		 requires that we treat this condition like normal EOF.  */
> +	      if (bytes < 0 && errno == ENOENT)
> +		{
> +		  bytes = 0;
> +		  __set_errno (saved_errno);
> +		}
> +	      if (bytes < 0)
> +		dirp->errcode = errno;
> +
> +	      dp = NULL;
> +	      break;
> +	    }
> +	  dirp->size = (size_t) bytes;
> +
> +	  /* Reset the offset into the buffer.  */
> +	  dirp->offset = 0;
> +	}
> +
> +      dp = (struct dirent *) &dirp->data[dirp->offset];
> +
> +      reclen = dp->d_reclen;
> +
> +      dirp->offset += reclen;
> +
> +      dirp->filepos = dp->d_off;
> +
> +      if (reclen > offsetof (struct dirent, d_name) + NAME_MAX + 1)
> +	{
> +	  /* The record is very long.  It could still fit into the
> +	     caller-supplied buffer if we can skip padding at the
> +	     end.  */
> +	  size_t namelen = _D_EXACT_NAMLEN (dp);
> +	  if (namelen <= NAME_MAX)
> +	    reclen = offsetof (struct dirent, d_name) + namelen + 1;
> +	  else
> +	    {
> +	      /* The name is too long.  Ignore this file.  */
> +	      dirp->errcode = ENAMETOOLONG;
> +	      dp->d_ino = 0;
> +	      continue;
> +	    }
> +	}
> +
> +      /* Skip deleted and ignored files.  */
> +    }
> +  while (dp->d_ino == 0);
> +
> +  if (dp != NULL)
> +    {
> +      *result = memcpy (entry, dp, reclen);
> +      entry->d_reclen = reclen;
> +      ret = 0;
> +    }
> +  else
> +    {
> +      *result = NULL;
> +      ret = dirp->errcode;
> +    }
> +
> +  __libc_lock_unlock (dirp->lock);
> +
> +  return ret;
> +}
> +
> +weak_alias (__readdir_r, readdir_r)
> +#endif /* _DIRENT_MATCHES_DIRENT64  */
> diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/unix/sysv/linux/rewinddir.c
> similarity index 100%
> rename from sysdeps/posix/rewinddir.c
> rename to sysdeps/unix/sysv/linux/rewinddir.c
> diff --git a/sysdeps/posix/seekdir.c b/sysdeps/unix/sysv/linux/seekdir.c
> similarity index 100%
> rename from sysdeps/posix/seekdir.c
> rename to sysdeps/unix/sysv/linux/seekdir.c
> diff --git a/sysdeps/posix/telldir.c b/sysdeps/unix/sysv/linux/telldir.c
> similarity index 100%
> rename from sysdeps/posix/telldir.c
> rename to sysdeps/unix/sysv/linux/telldir.c
>
  

Patch

diff --git a/sysdeps/posix/readdir.c b/sysdeps/posix/readdir.c
deleted file mode 100644
index b36278b5f4..0000000000
--- a/sysdeps/posix/readdir.c
+++ /dev/null
@@ -1,127 +0,0 @@ 
-/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <string.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <assert.h>
-
-#include <dirstream.h>
-
-#ifndef __READDIR
-# define __READDIR __readdir
-# define __GETDENTS __getdents
-# define DIRENT_TYPE struct dirent
-# define __READDIR_ALIAS
-#endif
-
-/* Read a directory entry from DIRP.  */
-DIRENT_TYPE *
-__READDIR (DIR *dirp)
-{
-  DIRENT_TYPE *dp;
-  int saved_errno = errno;
-
-#if IS_IN (libc)
-  __libc_lock_lock (dirp->lock);
-#endif
-
-  do
-    {
-      size_t reclen;
-
-      if (dirp->offset >= dirp->size)
-	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread;
-	  ssize_t bytes;
-
-#ifndef _DIRENT_HAVE_D_RECLEN
-	  /* Fixed-size struct; must read one at a time (see below).  */
-	  maxread = sizeof *dp;
-#else
-	  maxread = dirp->allocation;
-#endif
-
-	  bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      /* On some systems getdents fails with ENOENT when the
-		 open directory has been rmdir'd already.  POSIX.1
-		 requires that we treat this condition like normal EOF.  */
-	      if (bytes < 0 && errno == ENOENT)
-		bytes = 0;
-
-	      /* Don't modifiy errno when reaching EOF.  */
-	      if (bytes == 0)
-		__set_errno (saved_errno);
-	      dp = NULL;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
-	}
-
-      dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
-
-#ifdef _DIRENT_HAVE_D_RECLEN
-      reclen = dp->d_reclen;
-#else
-      /* The only version of `struct dirent*' that lacks `d_reclen'
-	 is fixed-size.  */
-      assert (sizeof dp->d_name > 1);
-      reclen = sizeof *dp;
-      /* The name is not terminated if it is the largest possible size.
-	 Clobber the following byte to ensure proper null termination.  We
-	 read jst one entry at a time above so we know that byte will not
-	 be used later.  */
-      dp->d_name[sizeof dp->d_name] = '\0';
-#endif
-
-      dirp->offset += reclen;
-
-#ifdef _DIRENT_HAVE_D_OFF
-      dirp->filepos = dp->d_off;
-#else
-      dirp->filepos += reclen;
-#endif
-
-      /* Skip deleted files.  */
-    } while (dp->d_ino == 0);
-
-#if IS_IN (libc)
-  __libc_lock_unlock (dirp->lock);
-#endif
-
-  return dp;
-}
-
-#ifdef __READDIR_ALIAS
-weak_alias (__readdir, readdir)
-#endif
-
-#undef __READDIR
-#undef __GETDENTS
-#undef DIRENT_TYPE
-#undef __READDIR_ALIAS
diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c
deleted file mode 100644
index 9079abc2ff..0000000000
--- a/sysdeps/posix/readdir_r.c
+++ /dev/null
@@ -1,159 +0,0 @@ 
-/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <string.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <assert.h>
-
-#include <dirstream.h>
-
-#ifndef __READDIR_R
-# define __READDIR_R __readdir_r
-# define __GETDENTS __getdents
-# define DIRENT_TYPE struct dirent
-# define __READDIR_R_ALIAS
-#endif
-
-/* Read a directory entry from DIRP.  */
-int
-__READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
-{
-  DIRENT_TYPE *dp;
-  size_t reclen;
-  const int saved_errno = errno;
-  int ret;
-
-  __libc_lock_lock (dirp->lock);
-
-  do
-    {
-      if (dirp->offset >= dirp->size)
-	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread;
-	  ssize_t bytes;
-
-#ifndef _DIRENT_HAVE_D_RECLEN
-	  /* Fixed-size struct; must read one at a time (see below).  */
-	  maxread = sizeof *dp;
-#else
-	  maxread = dirp->allocation;
-#endif
-
-	  bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      /* On some systems getdents fails with ENOENT when the
-		 open directory has been rmdir'd already.  POSIX.1
-		 requires that we treat this condition like normal EOF.  */
-	      if (bytes < 0 && errno == ENOENT)
-		{
-		  bytes = 0;
-		  __set_errno (saved_errno);
-		}
-	      if (bytes < 0)
-		dirp->errcode = errno;
-
-	      dp = NULL;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
-	}
-
-      dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
-
-#ifdef _DIRENT_HAVE_D_RECLEN
-      reclen = dp->d_reclen;
-#else
-      /* The only version of `struct dirent*' that lacks `d_reclen'
-	 is fixed-size.  */
-      assert (sizeof dp->d_name > 1);
-      reclen = sizeof *dp;
-      /* The name is not terminated if it is the largest possible size.
-	 Clobber the following byte to ensure proper null termination.  We
-	 read just one entry at a time above so we know that byte will not
-	 be used later.  */
-      dp->d_name[sizeof dp->d_name] = '\0';
-#endif
-
-      dirp->offset += reclen;
-
-#ifdef _DIRENT_HAVE_D_OFF
-      dirp->filepos = dp->d_off;
-#else
-      dirp->filepos += reclen;
-#endif
-
-#ifdef NAME_MAX
-      if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
-	{
-	  /* The record is very long.  It could still fit into the
-	     caller-supplied buffer if we can skip padding at the
-	     end.  */
-	  size_t namelen = _D_EXACT_NAMLEN (dp);
-	  if (namelen <= NAME_MAX)
-	    reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
-	  else
-	    {
-	      /* The name is too long.  Ignore this file.  */
-	      dirp->errcode = ENAMETOOLONG;
-	      dp->d_ino = 0;
-	      continue;
-	    }
-	}
-#endif
-
-      /* Skip deleted and ignored files.  */
-    }
-  while (dp->d_ino == 0);
-
-  if (dp != NULL)
-    {
-      *result = memcpy (entry, dp, reclen);
-#ifdef _DIRENT_HAVE_D_RECLEN
-      entry->d_reclen = reclen;
-#endif
-      ret = 0;
-    }
-  else
-    {
-      *result = NULL;
-      ret = dirp->errcode;
-    }
-
-  __libc_lock_unlock (dirp->lock);
-
-  return ret;
-}
-
-#ifdef __READDIR_R_ALIAS
-weak_alias (__readdir_r, readdir_r)
-#endif
-
-#undef __READDIR_R
-#undef __GETDENTS
-#undef DIRENT_TYPE
-#undef __READDIR_R_ALIAS
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
index 953d590cff..649b6bcb78 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
@@ -47,9 +47,9 @@  struct dirent64
 #define d_fileno	d_ino	/* Backwards compatibility.  */
 
 #undef  _DIRENT_HAVE_D_NAMLEN
-#define _DIRENT_HAVE_D_RECLEN
-#define _DIRENT_HAVE_D_OFF
-#define _DIRENT_HAVE_D_TYPE
+#define _DIRENT_HAVE_D_RECLEN		1
+#define _DIRENT_HAVE_D_OFF		1
+#define _DIRENT_HAVE_D_TYPE		1
 
 /* Inform libc code that these two types are effectively identical.  */
 #define _DIRENT_MATCHES_DIRENT64	1
diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h
index 9e4df8a58b..82c38d9ef8 100644
--- a/sysdeps/unix/sysv/linux/bits/dirent.h
+++ b/sysdeps/unix/sysv/linux/bits/dirent.h
@@ -47,9 +47,9 @@  struct dirent64
 #define d_fileno	d_ino	/* Backwards compatibility.  */
 
 #undef  _DIRENT_HAVE_D_NAMLEN
-#define _DIRENT_HAVE_D_RECLEN
-#define _DIRENT_HAVE_D_OFF
-#define _DIRENT_HAVE_D_TYPE
+#define _DIRENT_HAVE_D_RECLEN		1
+#define _DIRENT_HAVE_D_OFF		1
+#define _DIRENT_HAVE_D_TYPE		1
 
 #if defined __OFF_T_MATCHES_OFF64_T && defined __INO_T_MATCHES_INO64_T
 /* Inform libc code that these two types are effectively identical.  */
diff --git a/sysdeps/posix/closedir.c b/sysdeps/unix/sysv/linux/closedir.c
similarity index 100%
rename from sysdeps/posix/closedir.c
rename to sysdeps/unix/sysv/linux/closedir.c
diff --git a/sysdeps/posix/dirfd.c b/sysdeps/unix/sysv/linux/dirfd.c
similarity index 100%
rename from sysdeps/posix/dirfd.c
rename to sysdeps/unix/sysv/linux/dirfd.c
diff --git a/sysdeps/posix/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
similarity index 100%
rename from sysdeps/posix/dirstream.h
rename to sysdeps/unix/sysv/linux/dirstream.h
diff --git a/sysdeps/posix/fdopendir.c b/sysdeps/unix/sysv/linux/fdopendir.c
similarity index 100%
rename from sysdeps/posix/fdopendir.c
rename to sysdeps/unix/sysv/linux/fdopendir.c
diff --git a/sysdeps/posix/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
similarity index 100%
rename from sysdeps/posix/opendir.c
rename to sysdeps/unix/sysv/linux/opendir.c
diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
index df7a92aa78..2e03e66e69 100644
--- a/sysdeps/unix/sysv/linux/readdir.c
+++ b/sysdeps/unix/sysv/linux/readdir.c
@@ -19,5 +19,68 @@ 
 #include <dirent.h>
 
 #if !_DIRENT_MATCHES_DIRENT64
-# include <sysdeps/posix/readdir.c>
+#include <dirstream.h>
+
+/* Read a directory entry from DIRP.  */
+struct dirent *
+__readdir (DIR *dirp)
+{
+  struct dirent *dp;
+  int saved_errno = errno;
+
+#if IS_IN (libc)
+  __libc_lock_lock (dirp->lock);
+#endif
+
+  do
+    {
+      size_t reclen;
+
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  bytes = __getdents (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		bytes = 0;
+
+	      /* Don't modifiy errno when reaching EOF.  */
+	      if (bytes == 0)
+		__set_errno (saved_errno);
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct dirent *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      /* Skip deleted files.  */
+    } while (dp->d_ino == 0);
+
+#if IS_IN (libc)
+  __libc_lock_unlock (dirp->lock);
+#endif
+
+  return dp;
+}
+weak_alias (__readdir, readdir)
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
index 7d4b0001b3..e4d56cb2ae 100644
--- a/sysdeps/unix/sysv/linux/readdir64.c
+++ b/sysdeps/unix/sysv/linux/readdir64.c
@@ -23,17 +23,71 @@ 
 #define readdir   __no_readdir_decl
 #define __readdir __no___readdir_decl
 #include <dirent.h>
+#undef __readdir
+#undef readdir
 
-#define __READDIR   __readdir64
-#define __GETDENTS  __getdents64
-#define DIRENT_TYPE struct dirent64
+/* Read a directory entry from DIRP.  */
+struct dirent64 *
+__readdir64 (DIR *dirp)
+{
+  struct dirent64 *dp;
+  int saved_errno = errno;
 
-#include <sysdeps/posix/readdir.c>
+#if IS_IN (libc)
+  __libc_lock_lock (dirp->lock);
+#endif
 
-#undef __readdir
-#undef readdir
+  do
+    {
+      size_t reclen;
+
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		bytes = 0;
+
+	      /* Don't modifiy errno when reaching EOF.  */
+	      if (bytes == 0)
+		__set_errno (saved_errno);
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
 
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct dirent64 *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      /* Skip deleted files.  */
+    } while (dp->d_ino == 0);
+
+#if IS_IN (libc)
+  __libc_lock_unlock (dirp->lock);
+#endif
+
+  return dp;
+}
 libc_hidden_def (__readdir64)
+
 #if _DIRENT_MATCHES_DIRENT64
 strong_alias (__readdir64, __readdir)
 weak_alias (__readdir64, readdir64)
@@ -45,10 +99,67 @@  weak_alias (__readdir64, readdir)
 versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
 # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 #  include <olddirent.h>
-#  define __READDIR   attribute_compat_text_section __old_readdir64
-#  define __GETDENTS  __old_getdents64
-#  define DIRENT_TYPE struct __old_dirent64
-#  include <sysdeps/posix/readdir.c>
+
+attribute_compat_text_section
+struct __old_dirent64 *
+__old_readdir64 (DIR *dirp)
+{
+  struct __old_dirent64 *dp;
+  int saved_errno = errno;
+
+#if IS_IN (libc)
+  __libc_lock_lock (dirp->lock);
+#endif
+
+  do
+    {
+      size_t reclen;
+
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		bytes = 0;
+
+	      /* Don't modifiy errno when reaching EOF.  */
+	      if (bytes == 0)
+		__set_errno (saved_errno);
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      /* Skip deleted files.  */
+    } while (dp->d_ino == 0);
+
+#if IS_IN (libc)
+  __libc_lock_unlock (dirp->lock);
+#endif
+
+  return dp;
+}
 libc_hidden_def (__old_readdir64)
 compat_symbol (libc, __old_readdir64, readdir64, GLIBC_2_1);
 # endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)  */
diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
index 6d589f36f5..c587787417 100644
--- a/sysdeps/unix/sysv/linux/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/readdir64_r.c
@@ -23,15 +23,100 @@ 
 #define readdir_r   __no_readdir_r_decl
 #define __readdir_r __no___readdir_r_decl
 #include <dirent.h>
+#undef __readdir_r
+#undef readdir_r
 
-#define __READDIR_R __readdir64_r
-#define __GETDENTS  __getdents64
-#define DIRENT_TYPE struct dirent64
+/* Read a directory entry from DIRP.  */
+int
+__readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
+{
+  struct dirent64 *dp;
+  size_t reclen;
+  const int saved_errno = errno;
+  int ret;
 
-#include <sysdeps/posix/readdir_r.c>
+  __libc_lock_lock (dirp->lock);
+
+  do
+    {
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  maxread = dirp->allocation;
+
+	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		{
+		  bytes = 0;
+		  __set_errno (saved_errno);
+		}
+	      if (bytes < 0)
+		dirp->errcode = errno;
+
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct dirent64 *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      if (reclen > offsetof (struct dirent64, d_name) + NAME_MAX + 1)
+	{
+	  /* The record is very long.  It could still fit into the
+	     caller-supplied buffer if we can skip padding at the
+	     end.  */
+	  size_t namelen = _D_EXACT_NAMLEN (dp);
+	  if (namelen <= NAME_MAX)
+	    reclen = offsetof (struct dirent64, d_name) + namelen + 1;
+	  else
+	    {
+	      /* The name is too long.  Ignore this file.  */
+	      dirp->errcode = ENAMETOOLONG;
+	      dp->d_ino = 0;
+	      continue;
+	    }
+	}
+
+      /* Skip deleted and ignored files.  */
+    }
+  while (dp->d_ino == 0);
+
+  if (dp != NULL)
+    {
+      *result = memcpy (entry, dp, reclen);
+      entry->d_reclen = reclen;
+      ret = 0;
+    }
+  else
+    {
+      *result = NULL;
+      ret = dirp->errcode;
+    }
+
+  __libc_lock_unlock (dirp->lock);
+
+  return ret;
+}
 
-#undef __readdir_r
-#undef readdir_r
 
 #if _DIRENT_MATCHES_DIRENT64
 strong_alias (__readdir64_r, __readdir_r)
@@ -44,10 +129,99 @@  weak_alias (__readdir64_r, readdir64_r)
 versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
 # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 #  include <olddirent.h>
-#  define __READDIR_R attribute_compat_text_section __old_readdir64_r
-#  define __GETDENTS  __old_getdents64
-#  define DIRENT_TYPE struct __old_dirent64
-#  include <sysdeps/posix/readdir_r.c>
+
+int
+attribute_compat_text_section
+__old_readdir64_r (DIR *dirp, struct __old_dirent64 *entry,
+		   struct __old_dirent64 **result)
+{
+  struct __old_dirent64 *dp;
+  size_t reclen;
+  const int saved_errno = errno;
+  int ret;
+
+  __libc_lock_lock (dirp->lock);
+
+  do
+    {
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  maxread = dirp->allocation;
+
+	  bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		{
+		  bytes = 0;
+		  __set_errno (saved_errno);
+		}
+	      if (bytes < 0)
+		dirp->errcode = errno;
+
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      if (reclen > offsetof (struct __old_dirent64, d_name) + NAME_MAX + 1)
+	{
+	  /* The record is very long.  It could still fit into the
+	     caller-supplied buffer if we can skip padding at the
+	     end.  */
+	  size_t namelen = _D_EXACT_NAMLEN (dp);
+	  if (namelen <= NAME_MAX)
+	    reclen = offsetof (struct __old_dirent64, d_name) + namelen + 1;
+	  else
+	    {
+	      /* The name is too long.  Ignore this file.  */
+	      dirp->errcode = ENAMETOOLONG;
+	      dp->d_ino = 0;
+	      continue;
+	    }
+	}
+
+      /* Skip deleted and ignored files.  */
+    }
+  while (dp->d_ino == 0);
+
+  if (dp != NULL)
+    {
+      *result = memcpy (entry, dp, reclen);
+      entry->d_reclen = reclen;
+      ret = 0;
+    }
+  else
+    {
+      *result = NULL;
+      ret = dirp->errcode;
+    }
+
+  __libc_lock_unlock (dirp->lock);
+
+  return ret;
+}
+
 compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
 # endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)  */
 #endif /* _DIRENT_MATCHES_DIRENT64  */
diff --git a/sysdeps/unix/sysv/linux/readdir_r.c b/sysdeps/unix/sysv/linux/readdir_r.c
index 30f237dbcc..0069041394 100644
--- a/sysdeps/unix/sysv/linux/readdir_r.c
+++ b/sysdeps/unix/sysv/linux/readdir_r.c
@@ -19,5 +19,96 @@ 
 #include <dirent.h>
 
 #if !_DIRENT_MATCHES_DIRENT64
-# include <sysdeps/posix/readdir_r.c>
-#endif
+/* Read a directory entry from DIRP.  */
+int
+__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+  struct dirent *dp;
+  size_t reclen;
+  const int saved_errno = errno;
+  int ret;
+
+  __libc_lock_lock (dirp->lock);
+
+  do
+    {
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread = dirp->allocation;
+	  ssize_t bytes;
+
+	  maxread = dirp->allocation;
+
+	  bytes = __getdents (dirp->fd, dirp->data, maxread);
+	  if (bytes <= 0)
+	    {
+	      /* On some systems getdents fails with ENOENT when the
+		 open directory has been rmdir'd already.  POSIX.1
+		 requires that we treat this condition like normal EOF.  */
+	      if (bytes < 0 && errno == ENOENT)
+		{
+		  bytes = 0;
+		  __set_errno (saved_errno);
+		}
+	      if (bytes < 0)
+		dirp->errcode = errno;
+
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct dirent *) &dirp->data[dirp->offset];
+
+      reclen = dp->d_reclen;
+
+      dirp->offset += reclen;
+
+      dirp->filepos = dp->d_off;
+
+      if (reclen > offsetof (struct dirent, d_name) + NAME_MAX + 1)
+	{
+	  /* The record is very long.  It could still fit into the
+	     caller-supplied buffer if we can skip padding at the
+	     end.  */
+	  size_t namelen = _D_EXACT_NAMLEN (dp);
+	  if (namelen <= NAME_MAX)
+	    reclen = offsetof (struct dirent, d_name) + namelen + 1;
+	  else
+	    {
+	      /* The name is too long.  Ignore this file.  */
+	      dirp->errcode = ENAMETOOLONG;
+	      dp->d_ino = 0;
+	      continue;
+	    }
+	}
+
+      /* Skip deleted and ignored files.  */
+    }
+  while (dp->d_ino == 0);
+
+  if (dp != NULL)
+    {
+      *result = memcpy (entry, dp, reclen);
+      entry->d_reclen = reclen;
+      ret = 0;
+    }
+  else
+    {
+      *result = NULL;
+      ret = dirp->errcode;
+    }
+
+  __libc_lock_unlock (dirp->lock);
+
+  return ret;
+}
+
+weak_alias (__readdir_r, readdir_r)
+#endif /* _DIRENT_MATCHES_DIRENT64  */
diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/unix/sysv/linux/rewinddir.c
similarity index 100%
rename from sysdeps/posix/rewinddir.c
rename to sysdeps/unix/sysv/linux/rewinddir.c
diff --git a/sysdeps/posix/seekdir.c b/sysdeps/unix/sysv/linux/seekdir.c
similarity index 100%
rename from sysdeps/posix/seekdir.c
rename to sysdeps/unix/sysv/linux/seekdir.c
diff --git a/sysdeps/posix/telldir.c b/sysdeps/unix/sysv/linux/telldir.c
similarity index 100%
rename from sysdeps/posix/telldir.c
rename to sysdeps/unix/sysv/linux/telldir.c