X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=io.c;h=bc5e110dd1765fcc63d561d014e94e52203262c9;hb=6ca2610cee82e0bc80331093b7a713f6fc593eec;hp=3f8757c25905784782a591fa14bf5c85ca66382f;hpb=3138213bc9a827a372ad9f8009ebcc5d8797ce2d;p=strace diff --git a/io.c b/io.c index 3f8757c2..bc5e110d 100644 --- a/io.c +++ b/io.c @@ -37,21 +37,12 @@ #include #endif -#ifdef HAVE_LONG_LONG_OFF_T -/* - * Hacks for systems that have a long long off_t - */ - -#define sys_pread64 sys_pread -#define sys_pwrite64 sys_pwrite -#endif - int sys_read(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); } else { if (syserror(tcp)) tprintf("%#lx", tcp->u_arg[1]); @@ -67,7 +58,7 @@ sys_write(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); tprintf(", %lu", tcp->u_arg[2]); } @@ -76,10 +67,7 @@ sys_write(struct tcb *tcp) #if HAVE_SYS_UIO_H void -tprint_iov(tcp, len, addr) -struct tcb * tcp; -unsigned long len; -unsigned long addr; +tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov) { #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 union { @@ -105,7 +93,7 @@ unsigned long addr; int failed = 0; if (!len) { - tprintf("[]"); + tprints("[]"); return; } size = len * sizeof_iov; @@ -121,24 +109,27 @@ unsigned long addr; } else { abbrev_end = end; } - tprintf("["); + tprints("["); for (cur = addr; cur < end; cur += sizeof_iov) { if (cur > addr) - tprintf(", "); + tprints(", "); if (cur >= abbrev_end) { - tprintf("..."); + tprints("..."); break; } if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) { - tprintf("?"); + tprints("?"); failed = 1; break; } - tprintf("{"); - printstr(tcp, (long) iov_iov_base, iov_iov_len); + tprints("{"); + if (decode_iov) + printstr(tcp, (long) iov_iov_base, iov_iov_len); + else + tprintf("%#lx", (long) iov_iov_base); tprintf(", %lu}", (unsigned long)iov_iov_len); } - tprintf("]"); + tprints("]"); if (failed) tprintf(" %#lx", addr); #undef sizeof_iov @@ -151,14 +142,14 @@ sys_readv(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); } else { if (syserror(tcp)) { tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); return 0; } - tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]); + tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); tprintf(", %lu", tcp->u_arg[2]); } return 0; @@ -169,8 +160,8 @@ sys_writev(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); - tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]); + tprints(", "); + tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); tprintf(", %lu", tcp->u_arg[2]); } return 0; @@ -184,7 +175,7 @@ sys_pread(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); } else { if (syserror(tcp)) tprintf("%#lx", tcp->u_arg[1]); @@ -206,7 +197,7 @@ sys_pwrite(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); #if UNIXWARE /* off_t is signed int */ @@ -218,6 +209,39 @@ sys_pwrite(struct tcb *tcp) } return 0; } + +#if _LFS64_LARGEFILE +int +sys_pread64(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + } else { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else + printstr(tcp, tcp->u_arg[1], tcp->u_rval); + tprintf(", %lu, ", tcp->u_arg[2]); + printllval(tcp, "%#llx", 3); + } + return 0; +} + +int +sys_pwrite64(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); + tprintf(", %lu, ", tcp->u_arg[2]); + printllval(tcp, "%#llx", 3); + } + return 0; +} +#endif /* _LFS64_LARGEFILE */ + #endif /* SVR4 */ #ifdef FREEBSD @@ -229,7 +253,7 @@ sys_sendfile(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printfd(tcp, tcp->u_arg[1]); tprintf(", %llu, %lu", LONG_LONG(tcp->u_arg[2], tcp->u_arg[3]), @@ -238,22 +262,22 @@ sys_sendfile(struct tcb *tcp) off_t offset; if (!tcp->u_arg[5]) - tprintf(", NULL"); + tprints(", NULL"); else { struct sf_hdtr hdtr; if (umove(tcp, tcp->u_arg[5], &hdtr) < 0) tprintf(", %#lx", tcp->u_arg[5]); else { - tprintf(", { "); - tprint_iov(tcp, hdtr.hdr_cnt, hdtr.headers); + tprints(", { "); + tprint_iov(tcp, hdtr.hdr_cnt, hdtr.headers, 1); tprintf(", %u, ", hdtr.hdr_cnt); - tprint_iov(tcp, hdtr.trl_cnt, hdtr.trailers); + tprint_iov(tcp, hdtr.trl_cnt, hdtr.trailers, 1); tprintf(", %u }", hdtr.hdr_cnt); } } if (!tcp->u_arg[6]) - tprintf(", NULL"); + tprints(", NULL"); else if (umove(tcp, tcp->u_arg[6], &offset) < 0) tprintf(", %#lx", tcp->u_arg[6]); else @@ -282,7 +306,7 @@ sys_pread(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); } else { if (syserror(tcp)) tprintf("%#lx", tcp->u_arg[1]); @@ -299,7 +323,7 @@ sys_pwrite(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); tprintf(", %lu, ", tcp->u_arg[2]); printllval(tcp, "%llu", PREAD_OFFSET_ARG); @@ -307,6 +331,39 @@ sys_pwrite(struct tcb *tcp) return 0; } +#if HAVE_SYS_UIO_H +int +sys_preadv(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + } else { + if (syserror(tcp)) { + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); + return 0; + } + tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); + tprintf(", %lu, ", tcp->u_arg[2]); + printllval(tcp, "%llu", PREAD_OFFSET_ARG); + } + return 0; +} + +int +sys_pwritev(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); + tprintf(", %lu, ", tcp->u_arg[2]); + printllval(tcp, "%llu", PREAD_OFFSET_ARG); + } + return 0; +} +#endif /* HAVE_SYS_UIO_H */ + int sys_sendfile(struct tcb *tcp) { @@ -314,74 +371,125 @@ sys_sendfile(struct tcb *tcp) off_t offset; printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printfd(tcp, tcp->u_arg[1]); - tprintf(", "); + tprints(", "); if (!tcp->u_arg[2]) - tprintf("NULL"); + tprints("NULL"); else if (umove(tcp, tcp->u_arg[2], &offset) < 0) tprintf("%#lx", tcp->u_arg[2]); else +#ifdef HAVE_LONG_LONG_OFF_T + tprintf("[%llu]", offset); +#else tprintf("[%lu]", offset); +#endif tprintf(", %lu", tcp->u_arg[3]); } return 0; } +static void +print_loff_t(struct tcb *tcp, long addr) +{ + loff_t offset; + + if (!addr) + tprints("NULL"); + else if (umove(tcp, addr, &offset) < 0) + tprintf("%#lx", addr); + else + tprintf("[%llu]", (unsigned long long int) offset); +} + int sys_sendfile64(struct tcb *tcp) { if (entering(tcp)) { - loff_t offset; - printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); printfd(tcp, tcp->u_arg[1]); - tprintf(", "); - if (!tcp->u_arg[2]) - tprintf("NULL"); - else if (umove(tcp, tcp->u_arg[2], &offset) < 0) - tprintf("%#lx", tcp->u_arg[2]); - else - tprintf("[%llu]", (unsigned long long int) offset); + tprints(", "); + print_loff_t(tcp, tcp->u_arg[2]); tprintf(", %lu", tcp->u_arg[3]); } return 0; } -#endif /* LINUX */ +static const struct xlat splice_flags[] = { +#ifdef SPLICE_F_MOVE + { SPLICE_F_MOVE, "SPLICE_F_MOVE" }, +#endif +#ifdef SPLICE_F_NONBLOCK + { SPLICE_F_NONBLOCK, "SPLICE_F_NONBLOCK" }, +#endif +#ifdef SPLICE_F_MORE + { SPLICE_F_MORE, "SPLICE_F_MORE" }, +#endif +#ifdef SPLICE_F_GIFT + { SPLICE_F_GIFT, "SPLICE_F_GIFT" }, +#endif + { 0, NULL }, +}; -#if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T int -sys_pread64(struct tcb *tcp) +sys_tee(struct tcb *tcp) { if (entering(tcp)) { + /* int fd_in */ printfd(tcp, tcp->u_arg[0]); - tprintf(", "); - } else { - if (syserror(tcp)) - tprintf("%#lx", tcp->u_arg[1]); - else - printstr(tcp, tcp->u_arg[1], tcp->u_rval); - tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%#llx", 3); + tprints(", "); + /* int fd_out */ + printfd(tcp, tcp->u_arg[1]); + tprints(", "); + /* size_t len */ + tprintf("%lu, ", tcp->u_arg[2]); + /* unsigned int flags */ + printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); } return 0; } int -sys_pwrite64(struct tcb *tcp) +sys_splice(struct tcb *tcp) { if (entering(tcp)) { + /* int fd_in */ printfd(tcp, tcp->u_arg[0]); - tprintf(", "); - printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); - tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%#llx", 3); + tprints(", "); + /* loff_t *off_in */ + print_loff_t(tcp, tcp->u_arg[1]); + tprints(", "); + /* int fd_out */ + printfd(tcp, tcp->u_arg[2]); + tprints(", "); + /* loff_t *off_out */ + print_loff_t(tcp, tcp->u_arg[3]); + tprints(", "); + /* size_t len */ + tprintf("%lu, ", tcp->u_arg[4]); + /* unsigned int flags */ + printflags(splice_flags, tcp->u_arg[5], "SPLICE_F_???"); } return 0; } -#endif + +int +sys_vmsplice(struct tcb *tcp) +{ + if (entering(tcp)) { + /* int fd */ + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + /* const struct iovec *iov, unsigned long nr_segs */ + tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); + tprints(", "); + /* unsigned int flags */ + printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); + } + return 0; +} +#endif /* LINUX */ int sys_ioctl(struct tcb *tcp) @@ -390,10 +498,10 @@ sys_ioctl(struct tcb *tcp) if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - tprintf(", "); + tprints(", "); iop = ioctl_lookup(tcp->u_arg[1]); if (iop) { - tprintf("%s", iop->symbol); + tprints(iop->symbol); while ((iop = ioctl_next_match(iop))) tprintf(" or %s", iop->symbol); } else @@ -401,8 +509,8 @@ sys_ioctl(struct tcb *tcp) ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]); } else { - int ret; - if (!(ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]))) + int ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]); + if (!ret) tprintf(", %#lx", tcp->u_arg[2]); else return ret - 1;