Merge patch (bug fix) from Jeremy F:
59-fix-readv-writev
Fix error returns for readv and writev (and select).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1342 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c
index d5641fd..8904c62 100644
--- a/coregrind/arch/x86-linux/vg_libpthread.c
+++ b/coregrind/arch/x86-linux/vg_libpthread.c
@@ -88,6 +88,16 @@
int my_do_syscall3 ( int syscallno,
int arg1, int arg2, int arg3 );
+static
+__inline__
+int is_kerror ( int res )
+{
+ if (res >= -4095 && res <= -1)
+ return 1;
+ else
+ return 0;
+}
+
#ifdef GLIBC_2_3
/* kludge by JRS (not from glibc) ... */
@@ -1999,18 +2009,34 @@
int VGL_(readv)(int fd, const struct iovec *iov, int count)
{
+ int res;
+
__my_pthread_testcancel();
wait_for_fd_to_be_readable_or_erring(fd);
__my_pthread_testcancel();
- return my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+ res = my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+ return res;
}
int VGL_(writev)(int fd, struct iovec *iov, int count)
{
+ int res;
+
__my_pthread_testcancel();
wait_for_fd_to_be_writable_or_erring(fd);
__my_pthread_testcancel();
- return my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+ res = my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+ return res;
}
extern
@@ -2310,17 +2336,6 @@
#include "vg_kerneliface.h"
static
-__inline__
-int is_kerror ( int res )
-{
- if (res >= -4095 && res <= -1)
- return 1;
- else
- return 0;
-}
-
-
-static
int my_do_syscall1 ( int syscallno, int arg1 )
{
int __res;
diff --git a/coregrind/vg_intercept.c b/coregrind/vg_intercept.c
index 36bd196..b3ec039 100644
--- a/coregrind/vg_intercept.c
+++ b/coregrind/vg_intercept.c
@@ -225,6 +225,11 @@
args[3] = (int)exceptfds;
args[4] = (int)timeout;
res = my_do_syscall1(__NR_select, (int)(&(args[0])) );
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
return res;
}
@@ -245,7 +250,14 @@
WEAK int VGL_(readv)(int fd, const struct iovec *iov, int count)
{
- return my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+ int res = my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+
+ return res;
}
int readv (int fd, const struct iovec *iov, int count)
@@ -259,7 +271,14 @@
WEAK int VGL_(writev)(int fd, const struct iovec *iov, int count)
{
- return my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+ int res = my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+
+ return res;
}
int writev (int fd, const struct iovec *iov, int count)
diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c
index d5641fd..8904c62 100644
--- a/coregrind/vg_libpthread.c
+++ b/coregrind/vg_libpthread.c
@@ -88,6 +88,16 @@
int my_do_syscall3 ( int syscallno,
int arg1, int arg2, int arg3 );
+static
+__inline__
+int is_kerror ( int res )
+{
+ if (res >= -4095 && res <= -1)
+ return 1;
+ else
+ return 0;
+}
+
#ifdef GLIBC_2_3
/* kludge by JRS (not from glibc) ... */
@@ -1999,18 +2009,34 @@
int VGL_(readv)(int fd, const struct iovec *iov, int count)
{
+ int res;
+
__my_pthread_testcancel();
wait_for_fd_to_be_readable_or_erring(fd);
__my_pthread_testcancel();
- return my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+ res = my_do_syscall3(__NR_readv, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+ return res;
}
int VGL_(writev)(int fd, struct iovec *iov, int count)
{
+ int res;
+
__my_pthread_testcancel();
wait_for_fd_to_be_writable_or_erring(fd);
__my_pthread_testcancel();
- return my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+ res = my_do_syscall3(__NR_writev, fd, (unsigned)iov, count);
+
+ if (is_kerror(res)) {
+ *(__errno_location()) = -res;
+ return -1;
+ }
+ return res;
}
extern
@@ -2310,17 +2336,6 @@
#include "vg_kerneliface.h"
static
-__inline__
-int is_kerror ( int res )
-{
- if (res >= -4095 && res <= -1)
- return 1;
- else
- return 0;
-}
-
-
-static
int my_do_syscall1 ( int syscallno, int arg1 )
{
int __res;