From: Mark Wielaard Date: Fri, 29 Aug 2014 14:28:30 +0000 (+0000) Subject: Use getdents64 syscall on linux. X-Git-Tag: svn/VALGRIND_3_10_0~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=455f32995dbdcb05fb4458c0955c10eaffb2199f;p=thirdparty%2Fvalgrind.git Use getdents64 syscall on linux. getdents has been deprecated since linux 2.4 and newer arches (arm64) might no longer provide the getdents syscall. Use getdents64 for reading the /proc/self/fd/ dir so --track-fds=yes works reliable on all arches. Without this the none/tests/fdleak*vgtest might fail. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14384 --- diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index ccac5bb531..a019dd845a 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -522,12 +522,12 @@ Int VG_(readlink) (const HChar* path, HChar* buf, UInt bufsiz) return sr_isError(res) ? -1 : sr_Res(res); } -Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count) +Int VG_(getdents64) (Int fd, struct vki_dirent64 *dirp, UInt count) { # if defined(VGO_linux) SysRes res; /* res = getdents( fd, dirp, count ); */ - res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count); + res = VG_(do_syscall3)(__NR_getdents64, fd, (UWord)dirp, count); return sr_isError(res) ? -1 : sr_Res(res); # elif defined(VGO_darwin) I_die_here; diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 8bd42aa4be..d9df953dc6 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -837,7 +837,7 @@ void VG_(init_preopened_fds)(void) // DDD: should probably use HAVE_PROC here or similar, instead. #if defined(VGO_linux) Int ret; - struct vki_dirent d; + struct vki_dirent64 d; SysRes f; f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0); @@ -846,7 +846,7 @@ void VG_(init_preopened_fds)(void) return; } - while ((ret = VG_(getdents)(sr_Res(f), &d, sizeof(d))) != 0) { + while ((ret = VG_(getdents64)(sr_Res(f), &d, sizeof(d))) != 0) { if (ret == -1) goto out; diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index 00505fda90..e93e6655a8 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -92,7 +92,7 @@ extern Int VG_(unlink) ( const HChar* file_name ); extern SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout); extern Int VG_(readlink)( const HChar* path, HChar* buf, UInt bufsize ); -extern Int VG_(getdents)( Int fd, struct vki_dirent *dirp, UInt count ); +extern Int VG_(getdents64)( Int fd, struct vki_dirent64 *dirp, UInt count ); extern const HChar* VG_(basename)( const HChar* path ); extern const HChar* VG_(dirname) ( const HChar* path ); diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index aba2fae708..c78e00ffec 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -1373,6 +1373,7 @@ struct vki_robust_list_head { // From linux-2.6.8.1/include/linux/dirent.h //---------------------------------------------------------------------- +/* This is the old compat structure to use with the old dirent syscall. */ struct vki_dirent { long d_ino; __vki_kernel_off_t d_off; @@ -1380,6 +1381,15 @@ struct vki_dirent { char d_name[256]; /* We must not include limits.h! */ }; +/* This is the new structure to use with the dirent64 syscall. */ +struct vki_dirent64 { + __vki_u64 d_ino; + __vki_s64 d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; /* Note we hard code a max file length here. */ +}; + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/fcntl.h //----------------------------------------------------------------------