summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-04-28 14:26:18 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2012-04-28 14:26:18 +0200
commite0bc222263cf47a43e1b26d55edb2ffadc8ccbff (patch)
tree6c7f91e344fa5007eb8f2ea9e57e26b3a6e7d261 /io.c
parent54432560a846a466341874c11c8400d4b00def1e (diff)
downloadstrace-e0bc222263cf47a43e1b26d55edb2ffadc8ccbff.tar.gz
strace-e0bc222263cf47a43e1b26d55edb2ffadc8ccbff.tar.bz2
strace-e0bc222263cf47a43e1b26d55edb2ffadc8ccbff.tar.xz
Fix recvmsg decode: do not show more data than actually returned
I noticed that "hostname -d" talks over netlink and gets 20 bytes of response, but we show entire 1024 bytes of iov. This changes fixes that. * defs.h: New function tprint_iov_upto. * io.c (tprint_iov_upto): Definition of this function. (tprint_iov): Call tprint_iov_upto. * net.c (do_msghdr): Add data_size parameter, pass it down to tprint_iov_upto. (printmsghdr): Add data_size parameter, pass it down to do_msghdr. (printmmsghdr): Call do_msghdr with data_size==ULONG_MAX. (sys_sendmsg): Call printmsghdr with data_size==ULONG_MAX. (sys_recvmsg): Call printmsghdr with data_size==tcp->u_rval. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'io.c')
-rw-r--r--io.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/io.c b/io.c
index 5e697ec..bf5baa2 100644
--- a/io.c
+++ b/io.c
@@ -30,6 +30,7 @@
#include "defs.h"
#include <fcntl.h>
+#include <limits.h>
#if HAVE_SYS_UIO_H
# include <sys/uio.h>
#endif
@@ -63,8 +64,12 @@ sys_write(struct tcb *tcp)
}
#if HAVE_SYS_UIO_H
+/*
+ * data_size limits the cumulative size of printed data.
+ * Example: recvmsg returing a short read.
+ */
void
-tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov)
+tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov, unsigned long data_size)
{
#if SUPPORTED_PERSONALITIES > 1
union {
@@ -117,9 +122,13 @@ tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_io
break;
}
tprints("{");
- if (decode_iov)
- printstr(tcp, (long) iov_iov_base, iov_iov_len);
- else
+ if (decode_iov) {
+ unsigned long len = iov_iov_len;
+ if (len > data_size)
+ len = data_size;
+ data_size -= len;
+ printstr(tcp, (long) iov_iov_base, len);
+ } else
tprintf("%#lx", (long) iov_iov_base);
tprintf(", %lu}", (unsigned long)iov_iov_len);
}
@@ -131,6 +140,12 @@ tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_io
#undef iov_iov_len
}
+void
+tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov)
+{
+ tprint_iov_upto(tcp, len, addr, decode_iov, ULONG_MAX);
+}
+
int
sys_readv(struct tcb *tcp)
{