X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=time.c;h=b5fdc5233c4f773c56117b6e242b122f2caccb07;hb=3138213bc9a827a372ad9f8009ebcc5d8797ce2d;hp=28c05bd28243fd652d57e185b6a33dece53fc441;hpb=54a4edd69a320542ddd0dffec05dacab7443d453;p=strace diff --git a/time.c b/time.c index 28c05bd2..b5fdc523 100644 --- a/time.c +++ b/time.c @@ -34,50 +34,177 @@ #ifdef LINUX #include #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 */ -void -printtv(tcp, addr) -struct tcb *tcp; -long addr; +struct timeval32 +{ + u_int32_t tv_sec, tv_usec; +}; + +static void +tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv) { - struct timeval tv; + tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec); +} + +static void +tprint_timeval(struct tcb *tcp, const struct timeval *tv) +{ + tprintf("{%lu, %lu}", + (unsigned long) tv->tv_sec, (unsigned long) tv->tv_usec); +} +void +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 if (umove(tcp, addr, &tv) < 0) - tprintf("{...}"); - else - tprintf("{%lu, %lu}", (long) tv.tv_sec, (long) tv.tv_usec); + else { + int rc; + + if (bitness == BITNESS_32 +#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 + || personality_wordsize[current_personality] == 4 +#endif + ) + { + struct timeval32 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_timeval32(tcp, &tv); + } + } else { + struct timeval 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("{...}"); + } } -#ifdef ALPHA -struct timeval32 +void +sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) { - unsigned tv_sec; - unsigned tv_usec; -}; + if (addr == 0) + strcpy(buf, "NULL"); + else if (!verbose(tcp)) + sprintf(buf, "%#lx", addr); + else { + int rc; -void -printtv32(tcp, addr) -struct tcb *tcp; -long addr; + if (bitness == BITNESS_32 +#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 + || personality_wordsize[current_personality] == 4 +#endif + ) + { + struct timeval32 tv; + + if ((rc = umove(tcp, addr, &tv)) >= 0) + sprintf(buf, "{%u, %u}", + tv.tv_sec, tv.tv_usec); + } else { + struct timeval tv; + + if ((rc = umove(tcp, addr, &tv)) >= 0) + sprintf(buf, "{%lu, %lu}", + (unsigned long) tv.tv_sec, + (unsigned long) tv.tv_usec); + } + if (rc < 0) + strcpy(buf, "{...}"); + } +} + +void print_timespec(struct tcb *tcp, long addr) { - struct timeval32 tv; + 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 (addr == 0) - tprintf("NULL"); - else if (!verbose(tcp)) - tprintf("%#lx", addr); - else if (umove(tcp, addr, &tv) < 0) - tprintf("{...}"); - else - tprintf("{%u, %u}", tv.tv_sec, tv.tv_usec); + 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, "{...}"); + } +} int sys_time(tcp) @@ -126,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; - } - printtv32(tcp, tcp->u_arg[0]); + 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(", "); - printtv32(tcp, tcp->u_arg[1]); + tprintf(", "); + printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); #endif /* !SVR4 */ - } - return 0; + } + return 0; } #endif @@ -161,14 +287,14 @@ int sys_osf_settimeofday(tcp) struct tcb *tcp; { - if (entering(tcp)) { - printtv32(tcp, tcp->u_arg[0]); + if (entering(tcp)) { + printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); #ifndef SVR4 - tprintf(", "); - printtv32(tcp, tcp->u_arg[1]); + tprintf(", "); + printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); #endif /* !SVR4 */ - } - return 0; + } + return 0; } #endif @@ -188,7 +314,22 @@ struct tcb *tcp; return 0; } -static struct xlat which[] = { +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"}, { ITIMER_PROF, "ITIMER_PROF" }, @@ -196,51 +337,50 @@ static struct xlat which[] = { }; static void -printitv(tcp, addr) -struct tcb *tcp; -long addr; +printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) { - struct itimerval itv; - if (addr == 0) tprintf("NULL"); else if (!verbose(tcp)) tprintf("%#lx", addr); - else if (umove(tcp, addr, &itv) < 0) - tprintf("{...}"); else { - tprintf("{it_interval={%lu, %lu}, it_value={%lu, %lu}}", - (long) itv.it_interval.tv_sec, (long) itv.it_interval.tv_usec, - (long) itv.it_value.tv_sec, (long) itv.it_value.tv_usec); - } -} + int rc; + if (bitness == BITNESS_32 +#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 + || personality_wordsize[current_personality] == 4 +#endif + ) + { + struct { + struct timeval32 it_interval, it_value; + } itv; -#ifdef ALPHA -static void -printitv32(tcp, addr) -struct tcb *tcp; -long addr; -{ - struct itimerval32 - { - struct timeval32 it_interval; - struct timeval32 it_value; - } itv; + 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 { + struct itimerval itv; - if (addr == 0) - tprintf("NULL"); - else if (!verbose(tcp)) - tprintf("%#lx", addr); - else if (umove(tcp, addr, &itv) < 0) - tprintf("{...}"); - else { - tprintf("{it_interval={%u, %u}, it_value={%u, %u}}", - itv.it_interval.tv_sec, itv.it_interval.tv_usec, - itv.it_value.tv_sec, itv.it_value.tv_usec); - } + 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("{...}"); + } } -#endif + +#define printitv(tcp, addr) \ + printitv_bitness((tcp), (addr), BITNESS_CURRENT) int sys_getitimer(tcp) @@ -264,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 - printitv32(tcp, tcp->u_arg[1]); - } - 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 @@ -300,74 +440,257 @@ int sys_osf_setitimer(tcp) struct tcb *tcp; { - if (entering(tcp)) { - printxval(which, tcp->u_arg[0], "ITIMER_???"); - tprintf(", "); - printitv32(tcp, tcp->u_arg[1]); - tprintf(", "); - } else { - if (syserror(tcp)) - tprintf("%#lx", tcp->u_arg[2]); - else - printitv32(tcp, tcp->u_arg[2]); - } - 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 #ifdef LINUX -int -sys_adjtimex(tcp) -struct tcb *tcp; +static const struct xlat adjtimex_modes[] = { + { 0, "0" }, +#ifdef ADJ_OFFSET + { ADJ_OFFSET, "ADJ_OFFSET" }, +#endif +#ifdef ADJ_FREQUENCY + { ADJ_FREQUENCY, "ADJ_FREQUENCY" }, +#endif +#ifdef ADJ_MAXERROR + { ADJ_MAXERROR, "ADJ_MAXERROR" }, +#endif +#ifdef ADJ_ESTERROR + { ADJ_ESTERROR, "ADJ_ESTERROR" }, +#endif +#ifdef ADJ_STATUS + { ADJ_STATUS, "ADJ_STATUS" }, +#endif +#ifdef ADJ_TIMECONST + { ADJ_TIMECONST, "ADJ_TIMECONST" }, +#endif +#ifdef ADJ_TICK + { ADJ_TICK, "ADJ_TICK" }, +#endif +#ifdef ADJ_OFFSET_SINGLESHOT + { ADJ_OFFSET_SINGLESHOT, "ADJ_OFFSET_SINGLESHOT" }, +#endif + { 0, NULL } +}; + +static const struct xlat adjtimex_status[] = { +#ifdef STA_PLL + { STA_PLL, "STA_PLL" }, +#endif +#ifdef STA_PPSFREQ + { STA_PPSFREQ, "STA_PPSFREQ" }, +#endif +#ifdef STA_PPSTIME + { STA_PPSTIME, "STA_PPSTIME" }, +#endif +#ifdef STA_FLL + { STA_FLL, "STA_FLL" }, +#endif +#ifdef STA_INS + { STA_INS, "STA_INS" }, +#endif +#ifdef STA_DEL + { STA_DEL, "STA_DEL" }, +#endif +#ifdef STA_UNSYNC + { STA_UNSYNC, "STA_UNSYNC" }, +#endif +#ifdef STA_FREQHOLD + { STA_FREQHOLD, "STA_FREQHOLD" }, +#endif +#ifdef STA_PPSSIGNAL + { STA_PPSSIGNAL, "STA_PPSSIGNAL" }, +#endif +#ifdef STA_PPSJITTER + { STA_PPSJITTER, "STA_PPSJITTER" }, +#endif +#ifdef STA_PPSWANDER + { STA_PPSWANDER, "STA_PPSWANDER" }, +#endif +#ifdef STA_PPSERROR + { STA_PPSERROR, "STA_PPSERROR" }, +#endif +#ifdef STA_CLOCKERR + { STA_CLOCKERR, "STA_CLOCKERR" }, +#endif + { 0, NULL } +}; + +static const struct xlat adjtimex_state[] = { +#ifdef TIME_OK + { TIME_OK, "TIME_OK" }, +#endif +#ifdef TIME_INS + { TIME_INS, "TIME_INS" }, +#endif +#ifdef TIME_DEL + { TIME_DEL, "TIME_DEL" }, +#endif +#ifdef TIME_OOP + { TIME_OOP, "TIME_OOP" }, +#endif +#ifdef TIME_WAIT + { TIME_WAIT, "TIME_WAIT" }, +#endif +#ifdef TIME_ERROR + { TIME_ERROR, "TIME_ERROR" }, +#endif + { 0, NULL } +}; + +#if SUPPORTED_PERSONALITIES > 1 +static int +tprint_timex32(struct tcb *tcp, long addr) { - struct timex txc; + struct { + unsigned int modes; + int offset; + int freq; + int maxerror; + int esterror; + int status; + int constant; + int precision; + int tolerance; + struct timeval32 time; + int tick; + int ppsfreq; + int jitter; + int shift; + int stabil; + int jitcnt; + int calcnt; + int errcnt; + int stbcnt; + } tx; + if (umove(tcp, addr, &tx) < 0) + return -1; + + tprintf("{modes="); + printflags(adjtimex_modes, tx.modes, "ADJ_???"); + tprintf(", offset=%d, freq=%d, maxerror=%d, ", + tx.offset, tx.freq, tx.maxerror); + tprintf("esterror=%u, status=", tx.esterror); + printflags(adjtimex_status, tx.status, "STA_???"); + tprintf(", constant=%d, precision=%u, ", + tx.constant, tx.precision); + tprintf("tolerance=%d, time=", tx.tolerance); + tprint_timeval32(tcp, &tx.time); + tprintf(", tick=%d, ppsfreq=%d, jitter=%d", + tx.tick, tx.ppsfreq, tx.jitter); + tprintf(", shift=%d, stabil=%d, jitcnt=%d", + tx.shift, tx.stabil, tx.jitcnt); + tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d", + tx.calcnt, tx.errcnt, tx.stbcnt); + tprintf("}"); + return 0; +} +#endif /* SUPPORTED_PERSONALITIES > 1 */ + +static int +tprint_timex(struct tcb *tcp, long addr) +{ + struct timex tx; + +#if SUPPORTED_PERSONALITIES > 1 + if (personality_wordsize[current_personality] == 4) + return tprint_timex32(tcp, addr); +#endif + if (umove(tcp, addr, &tx) < 0) + return -1; + +#if LINUX_VERSION_CODE < 66332 + tprintf("{mode=%d, offset=%ld, frequency=%ld, ", + tx.mode, tx.offset, tx.frequency); + tprintf("maxerror=%ld, esterror=%lu, status=%u, ", + tx.maxerror, tx.esterror, tx.status); + tprintf("time_constant=%ld, precision=%lu, ", + tx.time_constant, tx.precision); + tprintf("tolerance=%ld, time=", tx.tolerance); + tprint_timeval(tcp, &tx.time); +#else + tprintf("{modes="); + printflags(adjtimex_modes, tx.modes, "ADJ_???"); + tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ", + tx.offset, tx.freq, tx.maxerror); + tprintf("esterror=%lu, status=", tx.esterror); + printflags(adjtimex_status, tx.status, "STA_???"); + tprintf(", constant=%ld, precision=%lu, ", + tx.constant, tx.precision); + tprintf("tolerance=%ld, time=", tx.tolerance); + tprint_timeval(tcp, &tx.time); + tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld", + tx.tick, tx.ppsfreq, tx.jitter); + tprintf(", shift=%d, stabil=%ld, jitcnt=%ld", + tx.shift, tx.stabil, tx.jitcnt); + tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld", + tx.calcnt, tx.errcnt, tx.stbcnt); +#endif + tprintf("}"); + return 0; +} + +int +sys_adjtimex(struct tcb *tcp) +{ if (exiting(tcp)) { if (tcp->u_arg[0] == 0) tprintf("NULL"); else if (syserror(tcp) || !verbose(tcp)) tprintf("%#lx", tcp->u_arg[0]); - else if (umove(tcp, tcp->u_arg[0], &txc) < 0) + else if (tprint_timex(tcp, tcp->u_arg[0]) < 0) tprintf("{...}"); - else { -#if LINUX_VERSION_CODE < 66332 - tprintf("{mode=%d, offset=%ld, frequency=%ld, ", - txc.mode, txc.offset, txc.frequency); - tprintf("maxerror=%ld, esterror=%lu, status=%u, ", - txc.maxerror, txc.esterror, txc.status); - tprintf("time_constant=%ld, precision=%lu, ", - txc.time_constant, txc.precision); - tprintf("tolerance=%ld, time={%lu, %lu}}", - txc.tolerance, (long) txc.time.tv_sec, - (long) txc.time.tv_usec); -#else - tprintf("{modes=%d, offset=%ld, freq=%ld, ", - txc.modes, txc.offset, txc.freq); - tprintf("maxerror=%ld, esterror=%lu, status=%u, ", - txc.maxerror, txc.esterror, txc.status); - tprintf("constant=%ld, precision=%lu, ", - txc.constant, txc.precision); - tprintf("tolerance=%ld, time={%lu, %lu}}", - txc.tolerance, (long) txc.time.tv_sec, - (long) txc.time.tv_usec); - /* there's a bunch of other stuff, but it's not - * worth the time or the trouble to include */ -#endif - } + if (syserror(tcp)) + return 0; + tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval); + if (tcp->auxstr) + return RVAL_STR; } return 0; } -static struct xlat clockflags[] = { +static const struct xlat clockflags[] = { { TIMER_ABSTIME, "TIMER_ABSTIME" }, { 0, NULL } }; -static struct xlat clocknames[] = { +static const struct xlat clocknames[] = { +#ifdef CLOCK_REALTIME { CLOCK_REALTIME, "CLOCK_REALTIME" }, +#endif +#ifdef CLOCK_MONOTONIC { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, - { 0, NULL } +#endif +#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 @@ -405,7 +728,7 @@ struct tcb *tcp; if (entering(tcp)) { printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); tprintf(", "); - printflags(clockflags, tcp->u_arg[1]); + printflags(clockflags, tcp->u_arg[1], "TIMER_???"); tprintf(", "); printtv(tcp, tcp->u_arg[2]); tprintf(", "); @@ -421,7 +744,7 @@ struct tcb *tcp; #ifndef SIGEV_THREAD_ID # define SIGEV_THREAD_ID 4 #endif -static struct xlat sigev_value[] = { +static const struct xlat sigev_value[] = { { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" }, { SIGEV_NONE+1, "SIGEV_NONE" }, { SIGEV_THREAD+1, "SIGEV_THREAD" }, @@ -429,17 +752,66 @@ static struct xlat sigev_value[] = { { 0, NULL } }; +#if SUPPORTED_PERSONALITIES > 1 +static void +printsigevent32(struct tcb *tcp, long arg) +{ + struct { + int sigev_value; + int sigev_signo; + int sigev_notify; + + union { + int tid; + struct { + int function, attribute; + } thread; + } un; + } sev; + + if (umove(tcp, arg, &sev) < 0) + tprintf("{...}"); + else { + tprintf("{%#x, ", sev.sigev_value); + if (sev.sigev_notify == SIGEV_SIGNAL) + tprintf("%s, ", signame(sev.sigev_signo)); + else + tprintf("%u, ", sev.sigev_signo); + printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???"); + tprintf(", "); + if (sev.sigev_notify == SIGEV_THREAD_ID) + tprintf("{%d}", sev.un.tid); + else if (sev.sigev_notify == SIGEV_THREAD) + tprintf("{%#x, %#x}", + sev.un.thread.function, + sev.un.thread.attribute); + else + tprintf("{...}"); + tprintf("}"); + } +} +#endif + void -printsigevent(tcp, arg) -struct tcb *tcp; -long arg; +printsigevent(struct tcb *tcp, long arg) { struct sigevent sev; + +#if SUPPORTED_PERSONALITIES > 1 + if (personality_wordsize[current_personality] == 4) + { + printsigevent32(tcp, arg); + return; + } +#endif if (umove (tcp, arg, &sev) < 0) tprintf("{...}"); else { - tprintf("{%p, %u, ", sev.sigev_value.sival_ptr, - sev.sigev_signo); + tprintf("{%p, ", sev.sigev_value.sival_ptr); + if (sev.sigev_notify == SIGEV_SIGNAL) + tprintf("%s, ", signame(sev.sigev_signo)); + else + tprintf("%u, ", sev.sigev_signo); printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???"); tprintf(", "); if (sev.sigev_notify == SIGEV_THREAD_ID) @@ -461,17 +833,17 @@ sys_timer_create(tcp) struct tcb *tcp; { if (entering(tcp)) { - tprintf("%#lx, ", tcp->u_arg[0]); + printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); + tprintf(", "); printsigevent(tcp, tcp->u_arg[1]); tprintf(", "); } else { - if (syserror(tcp)) + void *p; + + if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &p) < 0) tprintf("%#lx", tcp->u_arg[2]); - else { - void *p; - umove(tcp, tcp->u_arg[2], &p); + else tprintf("{%p}", p); - } } return 0; } @@ -482,7 +854,7 @@ struct tcb *tcp; { if (entering(tcp)) { tprintf("%#lx, ", tcp->u_arg[0]); - printflags(clockflags, tcp->u_arg[1]); + printflags(clockflags, tcp->u_arg[1], "TIMER_???"); tprintf(", "); printitv(tcp, tcp->u_arg[2]); tprintf(", "); @@ -509,5 +881,158 @@ struct tcb *tcp; } return 0; } -#endif /* LINUX */ +static void +print_rtc(tcp, rt) +struct tcb *tcp; +const struct rtc_time *rt; +{ + tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, " + "tm_mday=%d, tm_mon=%d, tm_year=%d, ", + rt->tm_sec, rt->tm_min, rt->tm_hour, + rt->tm_mday, rt->tm_mon, rt->tm_year); + if (!abbrev(tcp)) + tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}", + rt->tm_wday, rt->tm_yday, rt->tm_isdst); + else + tprintf("...}"); +} + +int +rtc_ioctl(tcp, code, arg) +struct tcb *tcp; +long code; +long arg; +{ + switch (code) { + case RTC_ALM_SET: + case RTC_SET_TIME: + if (entering(tcp)) { + struct rtc_time rt; + if (umove(tcp, arg, &rt) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", "); + print_rtc(tcp, &rt); + } + } + break; + case RTC_ALM_READ: + case RTC_RD_TIME: + if (exiting(tcp)) { + struct rtc_time rt; + if (syserror(tcp) || umove(tcp, arg, &rt) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", "); + print_rtc(tcp, &rt); + } + } + break; + case RTC_IRQP_SET: + case RTC_EPOCH_SET: + if (entering(tcp)) + tprintf(", %lu", arg); + break; + case RTC_IRQP_READ: + case RTC_EPOCH_READ: + if (exiting(tcp)) + tprintf(", %lu", arg); + break; + case RTC_WKALM_SET: + if (entering(tcp)) { + struct rtc_wkalrm wk; + if (umove(tcp, arg, &wk) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {enabled=%d, pending=%d, ", + wk.enabled, wk.pending); + print_rtc(tcp, &wk.time); + tprintf("}"); + } + } + break; + case RTC_WKALM_RD: + if (exiting(tcp)) { + struct rtc_wkalrm wk; + if (syserror(tcp) || umove(tcp, arg, &wk) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {enabled=%d, pending=%d, ", + wk.enabled, wk.pending); + print_rtc(tcp, &wk.time); + tprintf("}"); + } + } + break; + default: + if (entering(tcp)) + tprintf(", %#lx", arg); + break; + } + 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 */