[uClibc-cvs] uClibc/libc/sysdeps/linux/common getdents.c,1.4,1.5 getdents64.c,NONE,1.1 Makefile,1.73,1.74 syscalls.c,1.96,1.97
Erik Andersen
andersen at codepoet.org
Tue Jan 28 11:06:06 UTC 2003
- Previous message: [uClibc-cvs] uClibc/test/misc dirent.c,NONE,1.1 fdopen.c,NONE,1.1 .cvsignore,1.2,1.3 Makefile,1.5,1.6
- Next message: [uClibc-cvs] uClibc/libc/misc/dirent dirstream.h,1.5,1.6 readdir.c,1.7,1.8 readdir64.c,1.8,1.9 readdir64_r.c,1.2,1.3 readdir_r.c,1.2,1.3 scandir64.c,1.6,1.7
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/cvs/uClibc/libc/sysdeps/linux/common
In directory winder:/tmp/cvs-serv17535/libc/sysdeps/linux/common
Modified Files:
Makefile syscalls.c
Added Files:
getdents.c getdents64.c
Log Message:
Fix scandir64 to not free the wrong pieces of memory (which could
and did cause segfaults) by adjusting the working scandir.c to
the the 64 thing. Fix up potential for mismatches between the
libc and kernel dirent structures, which could also cause ugly
problems.
-Erik
--- NEW FILE: getdents64.c ---
/* Copyright (C) 1993, 1995-2002 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <features.h>
#ifdef __UCLIBC_HAS_LFS__
#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <dirent.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sysdep.h>
#include <sys/syscall.h>
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
struct kernel_dirent64
{
uint64_t d_ino;
int64_t d_off;
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256];
};
#define __NR___syscall_getdents64 __NR_getdents64
static inline _syscall3(int, __syscall_getdents64, int, fd, unsigned char *, dirp, size_t, count);
ssize_t __getdents64 (int fd, char *buf, size_t nbytes)
{
struct dirent64 *dp;
off64_t last_offset = -1;
ssize_t retval;
size_t red_nbytes;
struct kernel_dirent64 *skdp, *kdp;
const size_t size_diff = (offsetof (struct dirent64, d_name)
- offsetof (struct kernel_dirent64, d_name));
red_nbytes = MIN (nbytes - ((nbytes /
(offsetof (struct dirent64, d_name) + 14)) * size_diff),
nbytes - size_diff);
dp = (struct dirent64 *) buf;
skdp = kdp = alloca (red_nbytes);
retval = __syscall_getdents64(fd, (char *)kdp, red_nbytes);
if (retval == -1)
return -1;
while ((char *) kdp < (char *) skdp + retval) {
const size_t alignment = __alignof__ (struct dirent64);
/* Since kdp->d_reclen is already aligned for the kernel structure
this may compute a value that is bigger than necessary. */
size_t new_reclen = ((kdp->d_reclen + size_diff + alignment - 1)
& ~(alignment - 1));
if ((char *) dp + new_reclen > buf + nbytes) {
/* Our heuristic failed. We read too many entries. Reset
the stream. */
assert (last_offset != -1);
lseek64(fd, last_offset, SEEK_SET);
if ((char *) dp == buf) {
/* The buffer the user passed in is too small to hold even
one entry. */
__set_errno (EINVAL);
return -1;
}
break;
}
last_offset = kdp->d_off;
dp->d_ino = kdp->d_ino;
dp->d_off = kdp->d_off;
dp->d_reclen = new_reclen;
dp->d_type = DT_UNKNOWN;
memcpy (dp->d_name, kdp->d_name,
kdp->d_reclen - offsetof (struct kernel_dirent64, d_name));
dp = (struct dirent64 *) ((char *) dp + new_reclen);
kdp = (struct kernel_dirent64 *) (((char *) kdp) + kdp->d_reclen);
}
return (char *) dp - buf;
}
#endif /* __UCLIBC_HAS_LFS__ */
Index: Makefile
===================================================================
RCS file: /var/cvs/uClibc/libc/sysdeps/linux/common/Makefile,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- Makefile 24 Jan 2003 11:52:51 -0000 1.73
+++ Makefile 28 Jan 2003 11:06:01 -0000 1.74
@@ -25,7 +25,7 @@
cmsg_nxthdr.c longjmp.c open64.c ftruncate64.c \
truncate64.c getrlimit64.c setrlimit64.c creat64.c mmap64.c \
llseek.c pread_write.c _exit.c setuid.c sync.c getdirname.c \
- sendfile64.c xstatconv.c
+ sendfile64.c xstatconv.c getdents.c getdents64.c
ifneq ($(strip $(EXCLUDE_BRK)),y)
CSRC+=sbrk.c
endif
Index: syscalls.c
===================================================================
RCS file: /var/cvs/uClibc/libc/sysdeps/linux/common/syscalls.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -d -r1.96 -r1.97
--- syscalls.c 24 Jan 2003 11:52:51 -0000 1.96
+++ syscalls.c 28 Jan 2003 11:06:02 -0000 1.97
@@ -1226,11 +1226,7 @@
//See llseek.c
//#define __NR_getdents 141
-#ifdef L_getdents
-#include <unistd.h>
-#include <dirent.h>
-_syscall3(int, getdents, int, fd, char *, dirp, size_t, count);
-#endif
+// See getdents.c
//#define __NR__newselect 142
#ifdef L__newselect
@@ -1766,13 +1762,7 @@
//#define __NR_madvise1 219 /* delete when C lib stub is removed */
//#define __NR_getdents64 220
-#ifdef L_getdents64
-#ifdef __UCLIBC_HAS_LFS__
-#include <unistd.h>
-#include <dirent.h>
-_syscall3(int, getdents64, int, fd, char *, dirp, size_t, count);
-#endif /* __UCLIBC_HAS_LFS__ */
-#endif
+// See getdents64.c
//#define __NR_fcntl64 221
#ifdef L__fcntl64
- Previous message: [uClibc-cvs] uClibc/test/misc dirent.c,NONE,1.1 fdopen.c,NONE,1.1 .cvsignore,1.2,1.3 Makefile,1.5,1.6
- Next message: [uClibc-cvs] uClibc/libc/misc/dirent dirstream.h,1.5,1.6 readdir.c,1.7,1.8 readdir64.c,1.8,1.9 readdir64_r.c,1.2,1.3 readdir_r.c,1.2,1.3 scandir64.c,1.6,1.7
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the uClibc-cvs
mailing list