Implement sendmmsg syscall decoder
* linux/dummy.h (sys_sendmmsg): Remove.
* linux/syscall.h (sys_sendmmsg): New prototype.
* net.c (printmmsghdr): Add index argument specifying the element in
mmsghdr array to print.
(decode_mmsg): New function, prints the whole mmsghdr array, its length
and message flags.
(sys_sendmmsg): New function.
(sys_recvmmsg): Use decode_mmsg to fix mmsghdr array decoding.
diff --git a/net.c b/net.c
index 266d9c1..e7c7b2b 100644
--- a/net.c
+++ b/net.c
@@ -1447,13 +1447,14 @@
}
static void
-printmmsghdr(struct tcb *tcp, long addr)
+printmmsghdr(struct tcb *tcp, long addr, unsigned int idx)
{
struct mmsghdr {
struct msghdr msg_hdr;
unsigned msg_len;
} mmsg;
+ addr += sizeof(mmsg) * idx;
if (umove(tcp, addr, &mmsg) < 0) {
tprintf("%#lx", addr);
return;
@@ -1463,6 +1464,30 @@
tprintf(", %u}", mmsg.msg_len);
}
+static void
+decode_mmsg(struct tcb *tcp)
+{
+ /* mmsgvec */
+ if (syserror(tcp)) {
+ tprintf("%#lx", tcp->u_arg[1]);
+ } else {
+ unsigned int len = tcp->u_rval;
+ unsigned int i;
+
+ tprints("{");
+ for (i = 0; i < len; ++i) {
+ if (i)
+ tprints(", ");
+ printmmsghdr(tcp, tcp->u_arg[1], i);
+ }
+ tprints("}");
+ }
+ /* vlen */
+ tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
+ /* flags */
+ printflags(msg_flags, tcp->u_arg[3], "MSG_???");
+}
+
#endif /* HAVE_SENDMSG */
/*
@@ -1627,6 +1652,24 @@
return 0;
}
+int
+sys_sendmmsg(struct tcb *tcp)
+{
+ if (entering(tcp)) {
+ /* sockfd */
+ tprintf("%d, ", (int) tcp->u_arg[0]);
+ if (!verbose(tcp)) {
+ tprintf("%#lx, %u, ",
+ tcp->u_arg[1], (unsigned int) tcp->u_arg[2]);
+ printflags(msg_flags, tcp->u_arg[3], "MSG_???");
+ }
+ } else {
+ if (verbose(tcp))
+ decode_mmsg(tcp);
+ }
+ return 0;
+}
+
#endif /* HAVE_SENDMSG */
int
@@ -1732,13 +1775,7 @@
return 0;
} else {
if (verbose(tcp)) {
- if (syserror(tcp))
- tprintf("%#lx", tcp->u_arg[1]);
- else
- printmmsghdr(tcp, tcp->u_arg[1]);
- tprintf(", %ld, ", tcp->u_arg[2]);
- /* flags */
- printflags(msg_flags, tcp->u_arg[3], "MSG_???");
+ decode_mmsg(tcp);
/* timeout on entrance */
tprintf(", %s", tcp->auxstr ? tcp->auxstr : "{...}");
free((void *) tcp->auxstr);