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 }
int sys_fcntl(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); printxval(fcntlcmds, tcp->u_arg[1], "F_???"); switch (tcp->u_arg[1]) { case F_SETFD: tprints(", "); printflags(fdflags, tcp->u_arg[2], "FD_???"); break; case F_SETOWN: case F_DUPFD: #ifdef F_DUPFD_CLOEXEC case F_DUPFD_CLOEXEC: #endif tprintf(", %ld", tcp->u_arg[2]); break; case F_SETFL: tprints(", "); tprint_open_modes(tcp->u_arg[2]); break; case F_SETLK: case F_SETLKW: tprints(", "); printflock(tcp, tcp->u_arg[2], 0); break; #if USE_PRINTFLOCK64 case F_SETLK64: case F_SETLKW64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 0); break; #endif /* USE_PRINTFLOCK64 */ #ifdef F_NOTIFY case F_NOTIFY: tprints(", "); printflags(notifyflags, tcp->u_arg[2], "DN_???"); break; #endif #ifdef F_SETLEASE case F_SETLEASE: tprints(", "); printxval(lockfcmds, tcp->u_arg[2], "F_???"); break; #endif } } else { switch (tcp->u_arg[1]) { case F_DUPFD: #ifdef F_DUPFD_CLOEXEC case F_DUPFD_CLOEXEC: #endif case F_SETFD: case F_SETFL: case F_SETLK: case F_SETLKW: case F_SETOWN: case F_GETOWN: #ifdef F_NOTIFY case F_NOTIFY: #endif #ifdef F_SETLEASE case F_SETLEASE: #endif break; case F_GETFD: if (syserror(tcp) || tcp->u_rval == 0) return 0; tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval); return RVAL_HEX|RVAL_STR; case F_GETFL: if (syserror(tcp)) return 0; tcp->auxstr = sprint_open_modes(tcp->u_rval); return RVAL_HEX|RVAL_STR; case F_GETLK: tprints(", "); printflock(tcp, tcp->u_arg[2], 1); break; #if USE_PRINTFLOCK64 case F_GETLK64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 1); break; #endif #ifdef F_GETLEASE case F_GETLEASE: if (syserror(tcp)) return 0; tcp->auxstr = xlookup(lockfcmds, tcp->u_rval); return RVAL_HEX|RVAL_STR; #endif default: tprintf(", %#lx", tcp->u_arg[2]); break; } } return 0; }
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 } }
int sys_fcntl(struct tcb *tcp) { if (entering(tcp)) { tprintf("%ld, ", tcp->u_arg[0]); printxval(fcntlcmds, tcp->u_arg[1], "F_???"); switch (tcp->u_arg[1]) { case F_SETFD: tprintf(", "); printflags(fdflags, tcp->u_arg[2], "FD_???"); break; case F_SETOWN: case F_DUPFD: #ifdef F_DUPFD_CLOEXEC case F_DUPFD_CLOEXEC: #endif tprintf(", %ld", tcp->u_arg[2]); break; case F_SETFL: tprintf(", "); tprint_open_modes(tcp->u_arg[2]); break; case F_SETLK: case F_SETLKW: #ifdef F_FREESP case F_FREESP: #endif tprintf(", "); printflock(tcp, tcp->u_arg[2], 0); break; #if _LFS64_LARGEFILE #ifdef F_FREESP64 case F_FREESP64: #endif /* Linux glibc defines SETLK64 as SETLK, even though the kernel has different values - as does Solaris. */ #if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK case F_SETLK64: #endif #if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW case F_SETLKW64: #endif tprintf(", "); printflock64(tcp, tcp->u_arg[2], 0); break; #endif #ifdef F_NOTIFY case F_NOTIFY: tprintf(", "); printflags(notifyflags, tcp->u_arg[2], "DN_???"); break; #endif #ifdef F_SETLEASE case F_SETLEASE: tprintf(", "); printxval(lockfcmds, tcp->u_arg[2], "F_???"); break; #endif } } else { switch (tcp->u_arg[1]) { case F_DUPFD: #ifdef F_DUPFD_CLOEXEC case F_DUPFD_CLOEXEC: #endif case F_SETFD: case F_SETFL: case F_SETLK: case F_SETLKW: case F_SETOWN: case F_GETOWN: #ifdef F_NOTIFY case F_NOTIFY: #endif #ifdef F_SETLEASE case F_SETLEASE: #endif break; case F_GETFD: if (syserror(tcp) || tcp->u_rval == 0) return 0; tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval); return RVAL_HEX|RVAL_STR; case F_GETFL: if (syserror(tcp)) return 0; tcp->auxstr = sprint_open_modes(tcp->u_rval); return RVAL_HEX|RVAL_STR; case F_GETLK: tprintf(", "); printflock(tcp, tcp->u_arg[2], 1); break; #if _LFS64_LARGEFILE #if defined(F_GETLK64) && F_GETLK64+0!=F_GETLK case F_GETLK64: #endif tprintf(", "); printflock64(tcp, tcp->u_arg[2], 1); break; #endif #ifdef F_GETLEASE case F_GETLEASE: if (syserror(tcp)) return 0; tcp->auxstr = xlookup(lockfcmds, tcp->u_rval); return RVAL_HEX|RVAL_STR; #endif default: tprintf(", %#lx", tcp->u_arg[2]); break; } } return 0; }