svn commit: trunk/uClibc/libc/sysdeps/linux/common

vapier at uclibc.org vapier at uclibc.org
Wed Feb 15 00:43:43 UTC 2006


Author: vapier
Date: 2006-02-14 16:43:42 -0800 (Tue, 14 Feb 2006)
New Revision: 14024

Log:
we cant simply alias getdents to getdents64 as they deal with structures of different sizes on 32bit hosts

Modified:
   trunk/uClibc/libc/sysdeps/linux/common/getdents.c
   trunk/uClibc/libc/sysdeps/linux/common/getdents64.c


Changeset:
Modified: trunk/uClibc/libc/sysdeps/linux/common/getdents.c
===================================================================
--- trunk/uClibc/libc/sysdeps/linux/common/getdents.c	2006-02-15 00:38:55 UTC (rev 14023)
+++ trunk/uClibc/libc/sysdeps/linux/common/getdents.c	2006-02-15 00:43:42 UTC (rev 14024)
@@ -24,8 +24,6 @@
  * version / arch details.
  */
 
-#if ! defined __UCLIBC_HAS_LFS__ || ! defined __NR_getdents64
-
 libc_hidden_proto(memcpy)
 libc_hidden_proto(lseek)
 
@@ -41,11 +39,14 @@
 	char d_name[256];
 };
 
+ssize_t attribute_hidden __getdents (int fd, char *buf, size_t nbytes);
+
+#if ! defined __UCLIBC_HAS_LFS__ || ! defined __NR_getdents64
+
 #define __NR___syscall_getdents __NR_getdents
 static inline _syscall3(int, __syscall_getdents, int, fd, unsigned char *, kdirp, size_t, count);
 
-ssize_t attribute_hidden __getdents (int fd, char *buf, size_t nbytes);
-ssize_t attribute_hidden __getdents (int fd, char *buf, size_t nbytes)
+ssize_t __getdents (int fd, char *buf, size_t nbytes)
 {
     struct dirent *dp;
     off_t last_offset = -1;
@@ -100,6 +101,34 @@
     return (char *) dp - buf;
 }
 
-attribute_hidden strong_alias(__getdents,__getdents64)
+#elif __WORDSIZE == 32
 
+libc_hidden_proto(memmove)
+
+extern attribute_hidden __typeof(__getdents) __getdents64;
+ssize_t __getdents (int fd, char *buf, size_t nbytes)
+{
+    struct dirent *dp;
+    struct dirent64 *dp64;
+    ssize_t ret = __getdents64 (fd, buf, nbytes);
+
+    if (ret <= 0)
+	return ret;
+
+    dp64 = (struct dirent64 *) buf;
+    buf += ret;
+    while ((void *) dp64 < (void *) buf) {
+	dp = (struct dirent *) dp64;
+	dp->d_ino = dp64->d_ino;
+	dp->d_off = dp64->d_off;
+	dp->d_reclen = dp64->d_reclen;
+	dp->d_type = dp64->d_type;
+	memmove (dp->d_name, dp64->d_name, dp->d_reclen - offsetof (struct dirent64, d_name));
+	memmove (dp64, dp, dp->d_reclen);
+	dp64 = ((void *) dp64) + dp->d_reclen;
+    }
+
+    return ret;
+}
+
 #endif

Modified: trunk/uClibc/libc/sysdeps/linux/common/getdents64.c
===================================================================
--- trunk/uClibc/libc/sysdeps/linux/common/getdents64.c	2006-02-15 00:38:55 UTC (rev 14023)
+++ trunk/uClibc/libc/sysdeps/linux/common/getdents64.c	2006-02-15 00:43:42 UTC (rev 14024)
@@ -95,8 +95,10 @@
     return (char *) dp - buf;
 }
 
+#if __WORDSIZE == 64
 /* since getdents doesnt give us d_type but getdents64 does, try and
  * use getdents64 as much as possible */
 attribute_hidden strong_alias(__getdents64,__getdents)
+#endif
 
 #endif /* __UCLIBC_HAS_LFS__ */




More information about the uClibc-cvs mailing list