mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
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.
This commit is contained in:
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
|||||||
|
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-13 Ulrich Drepper <drepper@redhat.com>
|
2000-08-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* posix/Makefile: Remove rules to generate glob package.
|
* posix/Makefile: Remove rules to generate glob package.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define DIRENT_TYPE struct dirent64
|
||||||
#define DIRENT_SET_DP_INO(dp, value) \
|
#define DIRENT_SET_DP_INO(dp, value) \
|
||||||
do { (dp)->d_ino = (value); (dp)->__pad = 0; } while (0)
|
do { (dp)->d_ino = (value); (dp)->__pad = 0; } while (0)
|
||||||
#define __getdents64 __no___getdents64_decl
|
#define __getdents64 __no___getdents64_decl
|
||||||
|
@ -11,7 +11,22 @@ libc {
|
|||||||
outb; outw; outl;
|
outb; outw; outl;
|
||||||
}
|
}
|
||||||
GLIBC_2.2 {
|
GLIBC_2.2 {
|
||||||
|
# functions used in other libraries
|
||||||
|
__xstat64; __fxstat64; __lxstat64;
|
||||||
|
|
||||||
|
# a*
|
||||||
|
alphasort64;
|
||||||
|
|
||||||
# New rlimit interface
|
# New rlimit interface
|
||||||
getrlimit; setrlimit; getrlimit64;
|
getrlimit; setrlimit; getrlimit64;
|
||||||
|
|
||||||
|
# r*
|
||||||
|
readdir64; readdir64_r;
|
||||||
|
|
||||||
|
# s*
|
||||||
|
scandir64;
|
||||||
|
|
||||||
|
# v*
|
||||||
|
versionsort64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,19 @@
|
|||||||
|
|
||||||
#include <linux/posix_types.h>
|
#include <linux/posix_types.h>
|
||||||
|
|
||||||
|
#include "kernel-features.h"
|
||||||
|
|
||||||
|
#ifdef __NR_getdents64
|
||||||
|
#ifndef __ASSUME_GETDENTS64_SYSCALL
|
||||||
|
#ifndef __GETDENTS
|
||||||
|
/* The variable is shared between all *getdents* calls. */
|
||||||
|
int __have_no_getdents64;
|
||||||
|
#else
|
||||||
|
extern int __have_no_getdents64;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||||
|
|
||||||
extern int __syscall_getdents (int fd, char *__unbounded buf, size_t nbytes);
|
extern int __syscall_getdents (int fd, char *__unbounded buf, size_t nbytes);
|
||||||
@ -51,8 +64,19 @@ struct kernel_dirent
|
|||||||
char d_name[256];
|
char d_name[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct kernel_dirent64
|
||||||
|
{
|
||||||
|
u_int64_t d_ino;
|
||||||
|
int64_t d_off;
|
||||||
|
unsigned short int d_reclen;
|
||||||
|
unsigned char d_type;
|
||||||
|
char d_name[256];
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef __GETDENTS
|
#ifndef __GETDENTS
|
||||||
# define __GETDENTS __getdents
|
# define __GETDENTS __getdents
|
||||||
|
#endif
|
||||||
|
#ifndef DIRENT_TYPE
|
||||||
# define DIRENT_TYPE struct dirent
|
# define DIRENT_TYPE struct dirent
|
||||||
#endif
|
#endif
|
||||||
#ifndef DIRENT_SET_DP_INO
|
#ifndef DIRENT_SET_DP_INO
|
||||||
@ -71,11 +95,102 @@ ssize_t
|
|||||||
internal_function
|
internal_function
|
||||||
__GETDENTS (int fd, char *buf, size_t nbytes)
|
__GETDENTS (int fd, char *buf, size_t nbytes)
|
||||||
{
|
{
|
||||||
|
DIRENT_TYPE *dp;
|
||||||
off_t last_offset = -1;
|
off_t last_offset = -1;
|
||||||
|
ssize_t retval;
|
||||||
|
|
||||||
|
#ifdef __NR_getdents64
|
||||||
|
#ifndef __ASSUME_GETDENTS64_SYSCALL
|
||||||
|
if (!__have_no_getdents64)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef __ASSUME_GETDENTS64_SYSCALL
|
||||||
|
int saved_errno = errno;
|
||||||
|
#endif
|
||||||
|
char *kbuf = buf;
|
||||||
|
size_t kbytes = nbytes;
|
||||||
|
if (offsetof (DIRENT_TYPE, d_name)
|
||||||
|
< offsetof (struct kernel_dirent64, d_name)
|
||||||
|
&& nbytes <= sizeof (DIRENT_TYPE))
|
||||||
|
{
|
||||||
|
kbytes = nbytes + offsetof (struct kernel_dirent64, d_name)
|
||||||
|
- offsetof (DIRENT_TYPE, d_name);
|
||||||
|
kbuf = __alloca(kbytes);
|
||||||
|
}
|
||||||
|
retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
|
||||||
|
kbytes);
|
||||||
|
#ifndef __ASSUME_GETDENTS64_SYSCALL
|
||||||
|
if (retval != -1 && errno != -EINVAL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
struct kernel_dirent64 *kdp;
|
||||||
|
const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)
|
||||||
|
- offsetof (DIRENT_TYPE, d_name));
|
||||||
|
|
||||||
|
/* If the structure returned by the kernel is identical to what we
|
||||||
|
need, don't do any conversions. */
|
||||||
|
if (offsetof (DIRENT_TYPE, d_name)
|
||||||
|
== offsetof (struct kernel_dirent64, d_name)
|
||||||
|
&& sizeof (dp->d_ino) == sizeof (kdp->d_ino)
|
||||||
|
&& sizeof (dp->d_off) == sizeof (kdp->d_off))
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
dp = (DIRENT_TYPE *)buf;
|
||||||
|
kdp = (struct kernel_dirent64 *)kbuf;
|
||||||
|
while ((char *) kdp < kbuf + retval)
|
||||||
|
{
|
||||||
|
const size_t alignment = __alignof__ (DIRENT_TYPE);
|
||||||
|
/* Since kdp->d_reclen is already aligned for the kernel
|
||||||
|
structure this may compute a value that is bigger
|
||||||
|
than necessary. */
|
||||||
|
size_t old_reclen = kdp->d_reclen;
|
||||||
|
size_t new_reclen = ((old_reclen - size_diff + alignment - 1)
|
||||||
|
& ~(alignment - 1));
|
||||||
|
u_int64_t d_ino = kdp->d_ino;
|
||||||
|
int64_t d_off = kdp->d_off;
|
||||||
|
unsigned char d_type = kdp->d_type;
|
||||||
|
|
||||||
|
DIRENT_SET_DP_INO(dp, d_ino);
|
||||||
|
dp->d_off = d_off;
|
||||||
|
if ((sizeof (dp->d_ino) != sizeof (kdp->d_ino)
|
||||||
|
&& dp->d_ino != d_ino)
|
||||||
|
|| (sizeof (dp->d_off) != sizeof (kdp->d_off)
|
||||||
|
&& dp->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)
|
||||||
|
{
|
||||||
|
__lseek (fd, last_offset, SEEK_SET);
|
||||||
|
return (char *) dp - buf;
|
||||||
|
}
|
||||||
|
__set_errno (EOVERFLOW);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_offset = d_off;
|
||||||
|
dp->d_reclen = new_reclen;
|
||||||
|
dp->d_type = d_type;
|
||||||
|
memmove (dp->d_name, kdp->d_name,
|
||||||
|
old_reclen - offsetof (struct kernel_dirent64, d_name));
|
||||||
|
|
||||||
|
dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);
|
||||||
|
kdp = (struct kernel_dirent64 *) ((char *) kdp + old_reclen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char *) dp - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef __ASSUME_GETDENTS64_SYSCALL
|
||||||
|
__set_errno (saved_errno);
|
||||||
|
__have_no_getdents64 = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
size_t red_nbytes;
|
size_t red_nbytes;
|
||||||
struct kernel_dirent *skdp, *kdp;
|
struct kernel_dirent *skdp, *kdp;
|
||||||
DIRENT_TYPE *dp;
|
|
||||||
int retval;
|
|
||||||
const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
|
const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
|
||||||
- offsetof (struct kernel_dirent, d_name));
|
- offsetof (struct kernel_dirent, d_name));
|
||||||
|
|
||||||
@ -129,6 +244,7 @@ __GETDENTS (int fd, char *buf, size_t nbytes)
|
|||||||
dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);
|
dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);
|
||||||
kdp = (struct kernel_dirent *) (((char *) kdp) + kdp->d_reclen);
|
kdp = (struct kernel_dirent *) (((char *) kdp) + kdp->d_reclen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (char *) dp - buf;
|
return (char *) dp - buf;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@ libc {
|
|||||||
# a*
|
# a*
|
||||||
alphasort64;
|
alphasort64;
|
||||||
|
|
||||||
# g*
|
|
||||||
getdirentries64;
|
|
||||||
# New rlimit interface
|
# New rlimit interface
|
||||||
getrlimit; setrlimit; getrlimit64;
|
getrlimit; setrlimit; getrlimit64;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ versioned_symbol (libc, __getdents64, getdents64, GLIBC_2_2);
|
|||||||
#define __GETDENTS __old_getdents64
|
#define __GETDENTS __old_getdents64
|
||||||
#define DIRENT_TYPE struct __old_dirent64
|
#define DIRENT_TYPE struct __old_dirent64
|
||||||
#define kernel_dirent old_kernel_dirent
|
#define kernel_dirent old_kernel_dirent
|
||||||
|
#define kernel_dirent64 old_kernel_dirent64
|
||||||
|
|
||||||
#include <sysdeps/unix/sysv/linux/getdents.c>
|
#include <sysdeps/unix/sysv/linux/getdents.c>
|
||||||
|
|
||||||
|
@ -136,3 +136,9 @@
|
|||||||
#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__)
|
#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__)
|
||||||
# define __ASSUME_FCNTL64 1
|
# define __ASSUME_FCNTL64 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The getdents64 syscall was introduced in 2.4.0-test7. We test for
|
||||||
|
2.4.1 for the earliest version we know the syscall is available. */
|
||||||
|
#if __LINUX_KERNEL_VERSION >= 132097
|
||||||
|
# define __ASSUME_GETDENTS64_SYSCALL 1
|
||||||
|
#endif
|
||||||
|
@ -9,11 +9,6 @@ libc {
|
|||||||
# functions used in other libraries
|
# functions used in other libraries
|
||||||
__xstat64; __fxstat64; __lxstat64;
|
__xstat64; __fxstat64; __lxstat64;
|
||||||
|
|
||||||
# a*
|
|
||||||
alphasort64;
|
|
||||||
|
|
||||||
# g*
|
|
||||||
getdirentries64;
|
|
||||||
# New rlimit interface
|
# New rlimit interface
|
||||||
getrlimit; setrlimit; getrlimit64; setrlimit64;
|
getrlimit; setrlimit; getrlimit64; setrlimit64;
|
||||||
|
|
||||||
@ -22,8 +17,5 @@ libc {
|
|||||||
|
|
||||||
# s*
|
# s*
|
||||||
scandir64;
|
scandir64;
|
||||||
|
|
||||||
# v*
|
|
||||||
versionsort64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,10 @@ libc {
|
|||||||
# functions used in other libraries
|
# functions used in other libraries
|
||||||
__xstat64; __fxstat64; __lxstat64;
|
__xstat64; __fxstat64; __lxstat64;
|
||||||
|
|
||||||
# a*
|
|
||||||
alphasort64;
|
|
||||||
|
|
||||||
# g*
|
|
||||||
getdirentries64;
|
|
||||||
|
|
||||||
# r*
|
# r*
|
||||||
readdir64; readdir64_r;
|
readdir64; readdir64_r;
|
||||||
|
|
||||||
# s*
|
# s*
|
||||||
scandir64;
|
scandir64;
|
||||||
|
|
||||||
# v*
|
|
||||||
versionsort64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user