X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=time.c;h=b5fdc5233c4f773c56117b6e242b122f2caccb07;hb=3138213bc9a827a372ad9f8009ebcc5d8797ce2d;hp=3d2f6c99c7b684889e596d3af72e8e809896738d;hpb=71d7089055b0ce830bf13d9322f06b87d6ce47c0;p=strace diff --git a/time.c b/time.c index 3d2f6c99..b5fdc523 100644 --- a/time.c +++ b/time.c @@ -36,6 +36,13 @@ #include #include #include + +#ifndef UTIME_NOW +#define UTIME_NOW ((1l << 30) - 1l) +#endif +#ifndef UTIME_OMIT +#define UTIME_OMIT ((1l << 30) - 2l) +#endif #endif /* LINUX */ struct timeval32 @@ -57,15 +64,14 @@ tprint_timeval(struct tcb *tcp, const struct timeval *tv) } void -printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) +printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special) { if (addr == 0) tprintf("NULL"); else if (!verbose(tcp)) tprintf("%#lx", addr); - else - { - int rc; + else { + int rc; if (bitness == BITNESS_32 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 @@ -75,16 +81,30 @@ printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) { struct timeval32 tv; - if ((rc = umove(tcp, addr, &tv)) >= 0) - tprint_timeval32(tcp, &tv); - } else - { + if ((rc = umove(tcp, addr, &tv)) >= 0) { + if (special && tv.tv_sec == 0 && + tv.tv_usec == UTIME_NOW) + tprintf("UTIME_NOW"); + else if (special && tv.tv_sec == 0 && + tv.tv_usec == UTIME_OMIT) + tprintf("UTIME_OMIT"); + else + tprint_timeval32(tcp, &tv); + } + } else { struct timeval tv; - if ((rc = umove(tcp, addr, &tv)) >= 0) - tprint_timeval(tcp, &tv); + if ((rc = umove(tcp, addr, &tv)) >= 0) { + if (special && tv.tv_sec == 0 && + tv.tv_usec == UTIME_NOW) + tprintf("UTIME_NOW"); + else if (special && tv.tv_sec == 0 && + tv.tv_usec == UTIME_OMIT) + tprintf("UTIME_OMIT"); + else + tprint_timeval(tcp, &tv); + } } - if (rc < 0) tprintf("{...}"); } @@ -97,9 +117,8 @@ sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) strcpy(buf, "NULL"); else if (!verbose(tcp)) sprintf(buf, "%#lx", addr); - else - { - int rc; + else { + int rc; if (bitness == BITNESS_32 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 @@ -112,8 +131,7 @@ sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) if ((rc = umove(tcp, addr, &tv)) >= 0) sprintf(buf, "{%u, %u}", tv.tv_sec, tv.tv_usec); - } else - { + } else { struct timeval tv; if ((rc = umove(tcp, addr, &tv)) >= 0) @@ -121,7 +139,68 @@ sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) (unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec); } + if (rc < 0) + strcpy(buf, "{...}"); + } +} +void print_timespec(struct tcb *tcp, long addr) +{ + if (addr == 0) + tprintf("NULL"); + else if (!verbose(tcp)) + tprintf("%#lx", addr); + else { + int rc; + +#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 + if (personality_wordsize[current_personality] == 4) { + struct timeval32 tv; + + if ((rc = umove(tcp, addr, &tv)) >= 0) + tprintf("{%u, %u}", + tv.tv_sec, tv.tv_usec); + } else +#endif + { + struct timespec ts; + + if ((rc = umove(tcp, addr, &ts)) >= 0) + tprintf("{%lu, %lu}", + (unsigned long) ts.tv_sec, + (unsigned long) ts.tv_nsec); + } + if (rc < 0) + tprintf("{...}"); + } +} + +void sprint_timespec(char *buf, struct tcb *tcp, long addr) +{ + if (addr == 0) + strcpy(buf, "NULL"); + else if (!verbose(tcp)) + sprintf(buf, "%#lx", addr); + else { + int rc; + +#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 + if (personality_wordsize[current_personality] == 4) { + struct timeval32 tv; + + if ((rc = umove(tcp, addr, &tv)) >= 0) + sprintf(buf, "{%u, %u}", + tv.tv_sec, tv.tv_usec); + } else +#endif + { + struct timespec ts; + + if ((rc = umove(tcp, addr, &ts)) >= 0) + sprintf(buf, "{%lu, %lu}", + (unsigned long) ts.tv_sec, + (unsigned long) ts.tv_nsec); + } if (rc < 0) strcpy(buf, "{...}"); } @@ -174,19 +253,18 @@ int sys_osf_gettimeofday(tcp) struct tcb *tcp; { - if (exiting(tcp)) { - if (syserror(tcp)) { - tprintf("%#lx, %#lx", - tcp->u_arg[0], tcp->u_arg[1]); - return 0; - } - printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32); + if (exiting(tcp)) { + if (syserror(tcp)) { + tprintf("%#lx, %#lx", tcp->u_arg[0], tcp->u_arg[1]); + return 0; + } + printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); #ifndef SVR4 - tprintf(", "); - printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32); + tprintf(", "); + printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); #endif /* !SVR4 */ - } - return 0; + } + return 0; } #endif @@ -209,14 +287,14 @@ int sys_osf_settimeofday(tcp) struct tcb *tcp; { - if (entering(tcp)) { - printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32); + if (entering(tcp)) { + printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); #ifndef SVR4 - tprintf(", "); - printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32); + tprintf(", "); + printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); #endif /* !SVR4 */ - } - return 0; + } + return 0; } #endif @@ -236,6 +314,21 @@ struct tcb *tcp; return 0; } +int +sys_nanosleep(struct tcb *tcp) +{ + if (entering(tcp)) { + print_timespec(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + if (!tcp->u_arg[1] || is_restart_error(tcp)) + print_timespec(tcp, tcp->u_arg[1]); + else + tprintf("%#lx", tcp->u_arg[1]); + } + return 0; +} + static const struct xlat which[] = { { ITIMER_REAL, "ITIMER_REAL" }, { ITIMER_VIRTUAL,"ITIMER_VIRTUAL"}, @@ -250,9 +343,8 @@ printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) tprintf("NULL"); else if (!verbose(tcp)) tprintf("%#lx", addr); - else - { - int rc; + else { + int rc; if (bitness == BITNESS_32 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 @@ -260,29 +352,28 @@ printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) #endif ) { - struct - { + struct { struct timeval32 it_interval, it_value; } itv; - if ((rc = umove(tcp, addr, &itv)) >= 0) + if ((rc = umove(tcp, addr, &itv)) >= 0) { tprintf("{it_interval="); tprint_timeval32(tcp, &itv.it_interval); tprintf(", it_value="); tprint_timeval32(tcp, &itv.it_value); tprintf("}"); - } else - { + } + } else { struct itimerval itv; - if ((rc = umove(tcp, addr, &itv)) >= 0) + if ((rc = umove(tcp, addr, &itv)) >= 0) { tprintf("{it_interval="); tprint_timeval(tcp, &itv.it_interval); tprintf(", it_value="); tprint_timeval(tcp, &itv.it_value); tprintf("}"); + } } - if (rc < 0) tprintf("{...}"); } @@ -313,16 +404,16 @@ int sys_osf_getitimer(tcp) struct tcb *tcp; { - if (entering(tcp)) { - printxval(which, tcp->u_arg[0], "ITIMER_???"); - tprintf(", "); - } else { - if (syserror(tcp)) - tprintf("%#lx", tcp->u_arg[1]); - else - printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); - } - return 0; + if (entering(tcp)) { + printxval(which, tcp->u_arg[0], "ITIMER_???"); + tprintf(", "); + } else { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else + printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); + } + return 0; } #endif @@ -349,18 +440,18 @@ int sys_osf_setitimer(tcp) struct tcb *tcp; { - if (entering(tcp)) { - printxval(which, tcp->u_arg[0], "ITIMER_???"); - tprintf(", "); - printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); - tprintf(", "); - } else { - if (syserror(tcp)) - tprintf("%#lx", tcp->u_arg[2]); - else - printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32); - } - return 0; + if (entering(tcp)) { + printxval(which, tcp->u_arg[0], "ITIMER_???"); + tprintf(", "); + printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); + tprintf(", "); + } else { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[2]); + else + printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32); + } + return 0; } #endif @@ -464,8 +555,7 @@ static const struct xlat adjtimex_state[] = { static int tprint_timex32(struct tcb *tcp, long addr) { - struct - { + struct { unsigned int modes; int offset; int freq; @@ -564,6 +654,8 @@ sys_adjtimex(struct tcb *tcp) tprintf("%#lx", tcp->u_arg[0]); else if (tprint_timex(tcp, tcp->u_arg[0]) < 0) tprintf("{...}"); + if (syserror(tcp)) + return 0; tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval); if (tcp->auxstr) return RVAL_STR; @@ -583,7 +675,22 @@ static const struct xlat clocknames[] = { #ifdef CLOCK_MONOTONIC { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, #endif - { 0, NULL } +#ifdef CLOCK_PROCESS_CPUTIME_ID + { CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID" }, +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + { CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID" }, +#endif +#ifdef CLOCK_MONOTONIC_RAW + { CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW" }, +#endif +#ifdef CLOCK_REALTIME_COARSE + { CLOCK_REALTIME_COARSE, "CLOCK_REALTIME_COARSE" }, +#endif +#ifdef CLOCK_MONOTONIC_COARSE + { CLOCK_MONOTONIC_COARSE, "CLOCK_MONOTONIC_COARSE" }, +#endif + { 0, NULL } }; int @@ -649,17 +756,14 @@ static const struct xlat sigev_value[] = { static void printsigevent32(struct tcb *tcp, long arg) { - struct - { + struct { int sigev_value; int sigev_signo; int sigev_notify; - union - { + union { int tid; - struct - { + struct { int function, attribute; } thread; } un; @@ -667,8 +771,7 @@ printsigevent32(struct tcb *tcp, long arg) if (umove(tcp, arg, &sev) < 0) tprintf("{...}"); - else - { + else { tprintf("{%#x, ", sev.sigev_value); if (sev.sigev_notify == SIGEV_SIGNAL) tprintf("%s, ", signame(sev.sigev_signo)); @@ -869,4 +972,67 @@ long arg; } return 1; } + +#ifndef TFD_TIMER_ABSTIME +#define TFD_TIMER_ABSTIME (1 << 0) +#endif + +static const struct xlat timerfdflags[] = { + { TFD_TIMER_ABSTIME, "TFD_TIMER_ABSTIME" }, + { 0, NULL } +}; + +int +sys_timerfd(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + /* It does not matter that the kernel uses itimerspec. */ + tprintf("%ld, ", tcp->u_arg[0]); + printxval(clocknames, tcp->u_arg[1], "CLOCK_???"); + tprintf(", "); + printflags(timerfdflags, tcp->u_arg[2], "TFD_???"); + tprintf(", "); + printitv(tcp, tcp->u_arg[3]); + } + return 0; +} + +int +sys_timerfd_create(struct tcb *tcp) +{ + if (entering(tcp)) { + printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); + tprintf(", "); + printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); + } + return 0; +} + +int +sys_timerfd_settime(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprintf(", "); + printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); + tprintf(", "); + printitv(tcp, tcp->u_arg[2]); + tprintf(", "); + printitv(tcp, tcp->u_arg[3]); + } + return 0; +} + +int +sys_timerfd_gettime(struct tcb *tcp) +{ + if (entering(tcp)) { + printfd(tcp, tcp->u_arg[0]); + tprintf(", "); + printitv(tcp, tcp->u_arg[1]); + } + return 0; +} + #endif /* LINUX */