void print_timespec(struct tcb *tcp, long addr) { char buf[TIMESPEC_TEXT_BUFSIZE]; sprint_timespec(buf, tcp, addr); tprints(buf); }
int sys_recvmmsg(struct tcb *tcp) { /* +5 chars are for "left " prefix */ static char str[5 + TIMESPEC_TEXT_BUFSIZE]; if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); if (verbose(tcp)) { sprint_timespec(str, tcp, tcp->u_arg[4]); /* Abusing tcp->auxstr as temp storage. * Will be used and freed on syscall exit. */ tcp->auxstr = strdup(str); } else { tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]); printflags(msg_flags, tcp->u_arg[3], "MSG_???"); tprints(", "); print_timespec(tcp, tcp->u_arg[4]); } return 0; } else { if (verbose(tcp)) { decode_mmsg(tcp, 0); /* timeout on entrance */ tprintf(", %s", tcp->auxstr ? tcp->auxstr : "{...}"); free((void *) tcp->auxstr); tcp->auxstr = NULL; } if (syserror(tcp)) return 0; if (tcp->u_rval == 0) { tcp->auxstr = "Timeout"; return RVAL_STR; } if (!verbose(tcp)) return 0; /* timeout on exit */ sprint_timespec(stpcpy(str, "left "), tcp, tcp->u_arg[4]); tcp->auxstr = str; return RVAL_STR; } }
static int decode_poll_exiting(struct tcb *const tcp, const kernel_ulong_t pts) { struct pollfd fds; const unsigned int nfds = tcp->u_arg[1]; const unsigned long size = sizeof(fds) * nfds; const kernel_ulong_t start = tcp->u_arg[0]; const kernel_ulong_t end = start + size; kernel_ulong_t cur; const unsigned int max_printed = abbrev(tcp) ? max_strlen : -1U; unsigned int printed; static char outstr[1024]; char *outptr; #define end_outstr (outstr + sizeof(outstr)) if (syserror(tcp)) return 0; if (tcp->u_rval == 0) { tcp->auxstr = "Timeout"; return RVAL_STR; } if (!verbose(tcp) || !start || !nfds || size / sizeof(fds) != nfds || end < start) return 0; outptr = outstr; for (printed = 0, cur = start; cur < end; cur += sizeof(fds)) { if (umove(tcp, cur, &fds) < 0) { if (outptr == outstr) *outptr++ = '['; else outptr = stpcpy(outptr, ", "); outptr += sprintf(outptr, "%#" PRI_klx, cur); break; } if (!fds.revents) continue; if (outptr == outstr) *outptr++ = '['; else outptr = stpcpy(outptr, ", "); if (printed >= max_printed) { outptr = stpcpy(outptr, "..."); break; } static const char fmt[] = "{fd=%d, revents="; char fdstr[sizeof(fmt) + sizeof(int) * 3]; sprintf(fdstr, fmt, fds.fd); const char *flagstr = sprintflags("", pollflags, (unsigned short) fds.revents); if (outptr + strlen(fdstr) + strlen(flagstr) + 1 >= end_outstr - (2 + 2 * sizeof(long) + sizeof(", ], ..."))) { outptr = stpcpy(outptr, "..."); break; } outptr = stpcpy(outptr, fdstr); outptr = stpcpy(outptr, flagstr); *outptr++ = '}'; ++printed; } if (outptr != outstr) *outptr++ = ']'; *outptr = '\0'; if (pts) { const char *str = sprint_timespec(tcp, pts); if (outptr + sizeof(", left ") + strlen(str) < end_outstr) { outptr = stpcpy(outptr, outptr == outstr ? "left " : ", left "); outptr = stpcpy(outptr, str); } else { outptr = stpcpy(outptr, ", ..."); } } if (outptr == outstr) return 0; tcp->auxstr = outstr; return RVAL_STR; #undef end_outstr }
static int decode_poll(struct tcb *tcp, long pts) { struct pollfd fds; unsigned nfds; unsigned long size, start, cur, end, abbrev_end; int failed = 0; if (entering(tcp)) { nfds = tcp->u_arg[1]; size = sizeof(fds) * nfds; start = tcp->u_arg[0]; end = start + size; if (nfds == 0 || size / sizeof(fds) != nfds || end < start) { tprintf("%#lx, %d, ", tcp->u_arg[0], nfds); return 0; } if (abbrev(tcp)) { abbrev_end = start + max_strlen * sizeof(fds); if (abbrev_end < start) abbrev_end = end; } else { abbrev_end = end; } tprints("["); for (cur = start; cur < end; cur += sizeof(fds)) { if (cur > start) tprints(", "); if (cur >= abbrev_end) { tprints("..."); break; } if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) { tprints("?"); failed = 1; break; } if (fds.fd < 0) { tprintf("{fd=%d}", fds.fd); continue; } tprints("{fd="); printfd(tcp, fds.fd); tprints(", events="); printflags(pollflags, fds.events, "POLL???"); tprints("}"); } tprints("]"); if (failed) tprintf(" %#lx", start); tprintf(", %d, ", nfds); return 0; } else { static char outstr[1024]; char *outptr; #define end_outstr (outstr + sizeof(outstr)) const char *flagstr; if (syserror(tcp)) return 0; if (tcp->u_rval == 0) { tcp->auxstr = "Timeout"; return RVAL_STR; } nfds = tcp->u_arg[1]; size = sizeof(fds) * nfds; start = tcp->u_arg[0]; end = start + size; if (nfds == 0 || size / sizeof(fds) != nfds || end < start) return 0; if (abbrev(tcp)) { abbrev_end = start + max_strlen * sizeof(fds); if (abbrev_end < start) abbrev_end = end; } else { abbrev_end = end; } outptr = outstr; for (cur = start; cur < end; cur += sizeof(fds)) { if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) { if (outptr < end_outstr - 2) *outptr++ = '?'; failed = 1; break; } if (!fds.revents) continue; if (outptr == outstr) { *outptr++ = '['; } else { if (outptr < end_outstr - 3) outptr = stpcpy(outptr, ", "); } if (cur >= abbrev_end) { if (outptr < end_outstr - 4) outptr = stpcpy(outptr, "..."); break; } if (outptr < end_outstr - (sizeof("{fd=%d, revents=") + sizeof(int)*3) + 1) outptr += sprintf(outptr, "{fd=%d, revents=", fds.fd); flagstr = sprintflags("", pollflags, fds.revents); if (outptr < end_outstr - (strlen(flagstr) + 2)) { outptr = stpcpy(outptr, flagstr); *outptr++ = '}'; } } if (failed) return 0; if (outptr != outstr /* && outptr < end_outstr - 1 (always true)*/) *outptr++ = ']'; *outptr = '\0'; if (pts) { if (outptr < end_outstr - (10 + TIMESPEC_TEXT_BUFSIZE)) { outptr = stpcpy(outptr, outptr == outstr ? "left " : ", left "); sprint_timespec(outptr, tcp, pts); } } if (outptr == outstr) return 0; tcp->auxstr = outstr; return RVAL_STR; #undef end_outstr } }