summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/common/getdents64.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/common/getdents64.c')
-rw-r--r--libc/sysdeps/linux/common/getdents64.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/libc/sysdeps/linux/common/getdents64.c b/libc/sysdeps/linux/common/getdents64.c
index 37cb4c6f8..30686f25a 100644
--- a/libc/sysdeps/linux/common/getdents64.c
+++ b/libc/sysdeps/linux/common/getdents64.c
@@ -5,7 +5,6 @@
*/
#include <features.h>
-#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <dirent.h>
@@ -17,6 +16,7 @@
#include <sys/types.h>
#include <sys/syscall.h>
#include <bits/kernel_types.h>
+#include <bits/uClibc_alloc.h>
#if defined __UCLIBC_HAS_LFS__ && defined __NR_getdents64
@@ -52,11 +52,13 @@ ssize_t __getdents64 (int fd, char *buf, size_t nbytes)
nbytes - size_diff);
dp = (struct dirent64 *) buf;
- skdp = kdp = alloca (red_nbytes);
+ skdp = kdp = stack_heap_alloc(red_nbytes);
retval = __syscall_getdents64(fd, (unsigned char *)kdp, red_nbytes);
- if (retval == -1)
+ if (retval == -1) {
+ stack_heap_free(skdp);
return -1;
+ }
while ((char *) kdp < (char *) skdp + retval) {
const size_t alignment = __alignof__ (struct dirent64);
@@ -73,6 +75,7 @@ ssize_t __getdents64 (int fd, char *buf, size_t nbytes)
if ((char *) dp == buf) {
/* The buffer the user passed in is too small to hold even
one entry. */
+ stack_heap_free(skdp);
__set_errno (EINVAL);
return -1;
}
@@ -89,6 +92,7 @@ ssize_t __getdents64 (int fd, char *buf, size_t nbytes)
dp = (struct dirent64 *) ((char *) dp + new_reclen);
kdp = (struct kernel_dirent64 *) (((char *) kdp) + kdp->d_reclen);
}
+ stack_heap_free(skdp);
return (char *) dp - buf;
}