aboutsummaryrefslogtreecommitdiff
path: root/include/pub_tool_libcfile.h
diff options
context:
space:
mode:
authorsewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9>2008-08-19 07:03:04 +0000
committersewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9>2008-08-19 07:03:04 +0000
commitec61b6509566cf36ab3968d69226cecf177cb0fe (patch)
tree3ea7d6e3548c366debd565ca33e140abcf08a5e4 /include/pub_tool_libcfile.h
parent419060073e7943846cc9e0bcdcb25258d90da2dc (diff)
downloadvalgrind-ec61b6509566cf36ab3968d69226cecf177cb0fe.tar.gz
Presently, Valgrind (non-client) code that wants to use the stat
family of syscalls is impossible to write in a way that's portable and correct. On some targets (eg x86-linux) you need to do sys_stat64 and receive the results in a 'struct vki_stat64'. But on other targets (eg amd64-linux) neither sys_stat64 nor 'struct vki_stat64' exist. This commit adds a new type, 'struct vg_stat', which contains 64 bit fields in all the right places, and makes VG_(stat) and VG_(fstat) use it. This means callers to the two functions no longer need to worry about the is-it-64-bit-clean-or-not question, since these routines reformat the received data into a'struct vg_stat'. Kind of like what glibc must have been doing for decades. This (indirectly) fixes a bug on x86-linux, in which m_debuginfo would sometimes fail to read debug info, due to VG_(di_notify_mmap) using VG_(stat) (hence sys_stat) on the file, which failed, and when in fact it should have used sys_stat64. Bug reported and tracked down by Marc-Oliver Straub. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8522 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'include/pub_tool_libcfile.h')
-rw-r--r--include/pub_tool_libcfile.h30
1 files changed, 28 insertions, 2 deletions
diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h
index 9e3274b35..81710d4d9 100644
--- a/include/pub_tool_libcfile.h
+++ b/include/pub_tool_libcfile.h
@@ -37,6 +37,32 @@
/* To use this file you must first include pub_tool_vki.h. */
+/* Note that VG_(stat) and VG_(fstat) write to a 'struct vg_stat*' and
+ not a 'struct vki_stat*' or a 'struct vki_stat64*'. 'struct
+ vg_stat*' is not the same as either of the vki_ versions. No
+ specific vki_stat{,64} kernel structure will work and is
+ consistently available on different architectures on Linux, so we
+ have to use this 'struct vg_stat' impedance-matching type
+ instead. */
+struct vg_stat {
+ ULong st_dev;
+ ULong st_ino;
+ ULong st_nlink;
+ UInt st_mode;
+ UInt st_uid;
+ UInt st_gid;
+ ULong st_rdev;
+ Long st_size;
+ ULong st_blksize;
+ ULong st_blocks;
+ ULong st_atime;
+ ULong st_atime_nsec;
+ ULong st_mtime;
+ ULong st_mtime_nsec;
+ ULong st_ctime;
+ ULong st_ctime_nsec;
+};
+
extern SysRes VG_(open) ( const Char* pathname, Int flags, Int mode );
extern void VG_(close) ( Int fd );
extern Int VG_(read) ( Int fd, void* buf, Int count);
@@ -44,8 +70,8 @@ extern Int VG_(write) ( Int fd, const void* buf, Int count);
extern Int VG_(pipe) ( Int fd[2] );
extern OffT VG_(lseek) ( Int fd, OffT offset, Int whence );
-extern SysRes VG_(stat) ( Char* file_name, struct vki_stat* buf );
-extern Int VG_(fstat) ( Int fd, struct vki_stat* buf );
+extern SysRes VG_(stat) ( Char* file_name, struct vg_stat* buf );
+extern Int VG_(fstat) ( Int fd, struct vg_stat* buf );
extern SysRes VG_(dup) ( Int oldfd );
extern Int VG_(rename) ( Char* old_name, Char* new_name );
extern Int VG_(unlink) ( Char* file_name );