2018-02-28 18:37:17 +00:00
|
|
|
/* Get directory entries. Linux non-LFS version.
|
2019-01-01 00:11:28 +00:00
|
|
|
Copyright (C) 1993-2019 Free Software Foundation, Inc.
|
1997-01-06 22:07:28 +00:00
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 04:58:11 +00:00
|
|
|
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.
|
1997-01-06 22:07:28 +00:00
|
|
|
|
|
|
|
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
|
2001-07-06 04:58:11 +00:00
|
|
|
Lesser General Public License for more details.
|
1997-01-06 22:07:28 +00:00
|
|
|
|
2001-07-06 04:58:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2018-02-28 18:37:17 +00:00
|
|
|
License along with the GNU C Library. If not, see
|
2012-02-09 23:18:22 +00:00
|
|
|
<http://www.gnu.org/licenses/>. */
|
1997-01-06 22:07:28 +00:00
|
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
#if !_DIRENT_MATCHES_DIRENT64
|
1998-10-21 15:29:52 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
# include <unistd.h>
|
|
|
|
# include <string.h>
|
|
|
|
# include <errno.h>
|
1997-01-06 22:07:28 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
# ifndef DIRENT_SET_DP_INO
|
|
|
|
# define DIRENT_SET_DP_INO(dp, value) (dp)->d_ino = (value)
|
|
|
|
# endif
|
Update.
2000-08-14 Jakub Jelinek <jakub@redhat.com>
* dirent/Versions (getdirentries64): Export at GLIBC_2.2.
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_GETDENTS64_SYSCALL): Define.
* sysdeps/unix/sysv/linux/getdents.c (__getdents): Use getdents64
syscall if available to get d_type fields.
* sysdeps/unix/sysv/linux/alpha/getdents.c (DIRENT_TYPE): Define.
* sysdeps/unix/sysv/linux/arm/Versions (__xstat64, __fxstat64,
__lxstat64): Export at GLIBC_2.2.
(alphasort64, readdir64, readdir64_r, scandir64, versionsort64):
Likewise.
* sysdeps/unix/sysv/linux/i386/Versions (getdirentries64): Remove.
* sysdeps/unix/sysv/linux/i386/getdents64.c (kernel_dirent64): Define.
* sysdeps/unix/sysv/linux/powerpc/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
* sysdeps/unix/sysv/linux/sparc/sparc32/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
2000-08-14 17:41:59 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
/* Pack the dirent64 struct down into 32-bit offset/inode fields, and
|
|
|
|
ensure that no overflow occurs. */
|
update from main archive 970121
Thu Jan 23 04:06:42 1997 Ulrich Drepper <drepper@cygnus.com>
* Make-dist (.PHONY: dist): Remove duplicate declaration.
(README): Depend on version.h not version.c.
* Makefile (README): Depend on version.h not version.c.
* Makeconfig (inst_libdir, inst_slibdir, inst_includedir,
inst_datadir, inst_zonedir, inst_localedir, inst_i18ndir, inst_bindir,
inst_sbindir, inst_infodir, inst_sysconfdir): New variables. Same
as variable withough inst_ but prepended with $(install_root).
(localtime-time): Use $(inst_sysconfdir) not $(sysconfdir).
* Makefile (install-others): Use $(inst_includedir).
(gnu/stabs.h, gnu/lib-names.h): Use $(inst_includedir).
* Makerules (tons of install rules): Use inst_% variables.
* elf/Makefile: Likewise.
* hurd/Makefile: Likewise.
* intl/Makefile: Likewise.
* manual/Makefile: Likewise.
* po/Makefile: Likewise.
* sunrpc/Makefile: Likewise.
* sysdeps/mach/hurd/Makefile: Likewise.
* sysdeps/standalone/i386/force_cpu386/Makefile: Likewise.
* time/Makefile: Likewise.
* config.make.in: Revert patch from Sat Jan 18 22:15:26 1997,
leave install_root in place.
* gnu-versions.h (_GNU_GETOPT_INTERFACE_VERSION): Define to 2.
* posix/getopt.c (GETOPT_INTERFACE_VERSION): Define to 2.
* posix/getopt1.c (GETOPT_INTERFACE_VERSION): Define to 2.
* elf/Makefile [yes==$(has-ldconfig)]: Correct dependencies of
ldconfig.
(CFLAGS-dl-load.c): New variable, avoid gcc warning.
* sysdeps/mach/hurd/configure.in: Add _LIBC_REENTRENT to DEFINES.
* sysdeps/mach/hurd/getdents.c: Update copyright. De-ANSI-declfy.
* sysdeps/stub/getdents.c: Likewise. Correct return value.
* sysdeps/unix/getdents.c: Likewise.
* sysdeps/unix/sysv/getdents.c: Likewise.
* sysdeps/unix/readdir.c: Update copyright.
* sysdeps/unix/bsd/sony/newsos4/Makefile: Correct ifeq arguments.
* sysdeps/unix/bsd/sun/sunos4/Makefile: Likewise.
* sysdeps/unix/sysv/Makefile: Likewise.
* sysdeps/unix/sysv/linux/Makefile: Likewise.
* sysdeps/unix/sysv/linux/alpha/Makefile: Likewise.
* sysdeps/unix/sysv/linux/i386/Makefile: Likewise.
* sysdeps/unix/sysv/linux/Dist: Don't distribute kernel_termios.h,
but sys/kernel_termios.h.
* sysdeps/unix/sysv/linux/alpha/Dist: Likewise.
* sysdeps/unix/sysv/linux/Makefile [$(subdir)==termios]
(sysdep_headers): Add sys/kernel_termios.h.
* sysdeps/unix/sysv/linux/kernel_termios.h: Moved to...
* sysdeps/unix/sysv/linux/sys/kernel_termios.h: ...here.
* sysdeps/unix/sysv/linux/sys/tcgetattr.c: Use __kernel_termios and
__KERNEL_NCCS instead of kernel_termios and KERNEL_NCCS resp.
* sysdeps/unix/sysv/linux/alpha/ioctls.h: New file.
* sysdeps/unix/sysv/linux/getdents.c: Correct problems with alignment.
* sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove getdents.
Reported by Eirik Fuller <eirik@netcom.com>.
* time/Banner: Removed. Wrong and unnecessary information. It's now
in...
* time/README: New file.
* time/Makefile (distribute): Remove Banner, add README.
Wed Jan 22 13:19:56 1997 Richard Henderson <rth@tamu.edu>
* sysdeps/unix/sysv/linux/alpha/ioperm.c (platforms): Add Sable.
(init_iosys): Recognize /etc/alpha_systype as a four-tuple for
the purpose of supporting brand new systems.
(*): The type of iosys variables should be iosys_t.
1997-01-22 Paul Eggert <eggert@twinsun.com>
* strftime.c (_strftime_copytm):
New function, to work around Solaris 2.5 tzset bug.
Wed Jan 22 23:05:14 1997 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/mach/hurd/vdprintf.c: Complete de-ANSI-declfication.
* sysdeps/posix/pipestream.c (writedecl): Fix typo.
Reported by Marcus G. Daniels <marcus@shannon.sysc.pdx.edu>.
Wed Jan 22 13:58:56 1997 Andreas Jaeger <aj@arthur.pfalz.de>
* elf/Makefile (CFLAGS-dl-load.c): New Variable to keep gcc silent
since name_copy is initialized.
Wed Jan 22 16:58:12 1997 Ulrich Drepper <drepper@cygnus.com>
* stdio-common/Makefile (tests): Remove scanf11.
* stdio-common/scanf11.c: Removed.
* stdio-common/vfscanf.c Revert patch of Thu Jan 16 23:39:25 1997.
Although the Corrigendum 1 describes the result as implemented the
even more recent Amendement 1 seconds the position of ISO C:1990
where the %n directive has no effect on the assignment count.
* stdio-common/bug10.c: Likewise.
* stdio-common/scanf1.c: Likewise.
* stdio-common/scanf3.c: Likewise.
* stdio-common/scanf10.c: Likewise.
* stdio-common/tstdiomisc.c: Likewise.
* new-malloc/obstack.h: Don't define malloc using bcopy if malloc
is not available. This leads to problems since bcopy does not
return a value. Instead define _obstack_memcpy based on memcpy or
bcopy. This name isn't used outside obstack.h and so no problems
from using the memcpy function in a file including obstack.h can
result.
Reported by Martin Trapp <trapp@ipd.info.uni-karlsruhe.de>.
Tue Jan 21 18:35:55 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* misc/regexp.h (compile): Fix typos.
Tue Jan 21 01:01:59 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/sys/procfs.h (struct elf_prpsinfo): Fix
type of pr_{pid,ppid,pgrp,sid} fields.
* sysdeps/unix/sysv/linux/alpha/sys/procfs.h (struct
elf_prpsinfo): Likewise.
1997-01-23 04:24:20 +00:00
|
|
|
ssize_t
|
2018-02-28 18:37:17 +00:00
|
|
|
__getdents (int fd, char *buf, size_t nbytes)
|
1997-01-06 22:07:28 +00:00
|
|
|
{
|
2018-02-28 18:37:17 +00:00
|
|
|
union
|
|
|
|
{
|
|
|
|
/* For !_DIRENT_MATCHES_DIRENT64 kernel 'linux_dirent64' has the same
|
|
|
|
layout of 'struct dirent64'. */
|
|
|
|
struct dirent64 k;
|
|
|
|
struct dirent u;
|
|
|
|
char b[1];
|
|
|
|
} *kbuf = (void *) buf, *outp, *inp;
|
|
|
|
size_t kbytes = nbytes;
|
|
|
|
off64_t last_offset = -1;
|
Update.
2000-08-14 Jakub Jelinek <jakub@redhat.com>
* dirent/Versions (getdirentries64): Export at GLIBC_2.2.
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_GETDENTS64_SYSCALL): Define.
* sysdeps/unix/sysv/linux/getdents.c (__getdents): Use getdents64
syscall if available to get d_type fields.
* sysdeps/unix/sysv/linux/alpha/getdents.c (DIRENT_TYPE): Define.
* sysdeps/unix/sysv/linux/arm/Versions (__xstat64, __fxstat64,
__lxstat64): Export at GLIBC_2.2.
(alphasort64, readdir64, readdir64_r, scandir64, versionsort64):
Likewise.
* sysdeps/unix/sysv/linux/i386/Versions (getdirentries64): Remove.
* sysdeps/unix/sysv/linux/i386/getdents64.c (kernel_dirent64): Define.
* sysdeps/unix/sysv/linux/powerpc/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
* sysdeps/unix/sysv/linux/sparc/sparc32/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
2000-08-14 17:41:59 +00:00
|
|
|
ssize_t retval;
|
1999-04-27 13:06:39 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
# define size_diff (offsetof (struct dirent64, d_name) \
|
|
|
|
- offsetof (struct dirent, d_name))
|
|
|
|
char kbuftmp[sizeof (struct dirent) + size_diff];
|
|
|
|
if (nbytes <= sizeof (struct dirent))
|
|
|
|
kbuf = (void*) kbuftmp;
|
2004-03-01 21:34:36 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
retval = INLINE_SYSCALL_CALL (getdents64, fd, kbuf, kbytes);
|
|
|
|
if (retval == -1)
|
|
|
|
return -1;
|
2004-03-01 21:34:36 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
/* These two pointers might alias the same memory buffer.
|
|
|
|
Standard C requires that we always use the same type for them,
|
|
|
|
so we must use the union type. */
|
|
|
|
inp = kbuf;
|
|
|
|
outp = (void *) buf;
|
2004-03-01 21:34:36 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
while (&inp->b < &kbuf->b + retval)
|
1997-01-06 22:07:28 +00:00
|
|
|
{
|
2018-02-28 18:37:17 +00:00
|
|
|
const size_t alignment = _Alignof (struct dirent);
|
|
|
|
/* Since inp->k.d_reclen is already aligned for the kernel
|
|
|
|
structure this may compute a value that is bigger
|
|
|
|
than necessary. */
|
|
|
|
size_t old_reclen = inp->k.d_reclen;
|
|
|
|
size_t new_reclen = ((old_reclen - size_diff + alignment - 1)
|
|
|
|
& ~(alignment - 1));
|
|
|
|
|
|
|
|
/* Copy the data out of the old structure into temporary space.
|
|
|
|
Then copy the name, which may overlap if BUF == KBUF. */
|
|
|
|
const uint64_t d_ino = inp->k.d_ino;
|
|
|
|
const int64_t d_off = inp->k.d_off;
|
|
|
|
const uint8_t d_type = inp->k.d_type;
|
|
|
|
|
|
|
|
memmove (outp->u.d_name, inp->k.d_name,
|
|
|
|
old_reclen - offsetof (struct dirent64, d_name));
|
|
|
|
|
|
|
|
/* Now we have copied the data from INP and access only OUTP. */
|
|
|
|
|
|
|
|
DIRENT_SET_DP_INO (&outp->u, d_ino);
|
|
|
|
outp->u.d_off = d_off;
|
|
|
|
if ((sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)
|
|
|
|
&& outp->u.d_ino != d_ino)
|
|
|
|
|| (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)
|
|
|
|
&& outp->u.d_off != d_off))
|
|
|
|
{
|
|
|
|
/* Overflow. If there was at least one entry before this one,
|
|
|
|
return them without error, otherwise signal overflow. */
|
|
|
|
if (last_offset != -1)
|
|
|
|
{
|
|
|
|
__lseek64 (fd, last_offset, SEEK_SET);
|
|
|
|
return outp->b - buf;
|
|
|
|
}
|
|
|
|
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
last_offset = d_off;
|
|
|
|
outp->u.d_reclen = new_reclen;
|
|
|
|
outp->u.d_type = d_type;
|
|
|
|
|
|
|
|
inp = (void *) inp + old_reclen;
|
|
|
|
outp = (void *) outp + new_reclen;
|
|
|
|
}
|
Update.
2000-08-14 Jakub Jelinek <jakub@redhat.com>
* dirent/Versions (getdirentries64): Export at GLIBC_2.2.
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_GETDENTS64_SYSCALL): Define.
* sysdeps/unix/sysv/linux/getdents.c (__getdents): Use getdents64
syscall if available to get d_type fields.
* sysdeps/unix/sysv/linux/alpha/getdents.c (DIRENT_TYPE): Define.
* sysdeps/unix/sysv/linux/arm/Versions (__xstat64, __fxstat64,
__lxstat64): Export at GLIBC_2.2.
(alphasort64, readdir64, readdir64_r, scandir64, versionsort64):
Likewise.
* sysdeps/unix/sysv/linux/i386/Versions (getdirentries64): Remove.
* sysdeps/unix/sysv/linux/i386/getdents64.c (kernel_dirent64): Define.
* sysdeps/unix/sysv/linux/powerpc/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
* sysdeps/unix/sysv/linux/sparc/sparc32/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
2000-08-14 17:41:59 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
return outp->b - buf;
|
|
|
|
}
|
Update.
2000-08-14 Jakub Jelinek <jakub@redhat.com>
* dirent/Versions (getdirentries64): Export at GLIBC_2.2.
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_GETDENTS64_SYSCALL): Define.
* sysdeps/unix/sysv/linux/getdents.c (__getdents): Use getdents64
syscall if available to get d_type fields.
* sysdeps/unix/sysv/linux/alpha/getdents.c (DIRENT_TYPE): Define.
* sysdeps/unix/sysv/linux/arm/Versions (__xstat64, __fxstat64,
__lxstat64): Export at GLIBC_2.2.
(alphasort64, readdir64, readdir64_r, scandir64, versionsort64):
Likewise.
* sysdeps/unix/sysv/linux/i386/Versions (getdirentries64): Remove.
* sysdeps/unix/sysv/linux/i386/getdents64.c (kernel_dirent64): Define.
* sysdeps/unix/sysv/linux/powerpc/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
* sysdeps/unix/sysv/linux/sparc/sparc32/Versions (alphasort64,
getdirentries64, versionsort64): Remove.
2000-08-14 17:41:59 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
# undef DIRENT_SET_DP_INO
|
1997-01-06 22:07:28 +00:00
|
|
|
|
2018-02-28 18:37:17 +00:00
|
|
|
#endif /* _DIRENT_MATCHES_DIRENT64 */
|