]> granicus.if.org Git - strace/blobdiff - time.c
Fix UTIME_NOW/UTIME_OMIT decoding
[strace] / time.c
diff --git a/time.c b/time.c
index 521880825d6eb2c6f3472dfc8446b2fa810e870c..68efc803a898e177b9974dbfe824d52833856671 100644 (file)
--- a/time.c
+++ b/time.c
@@ -79,7 +79,7 @@ sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int spec
 
        if (bitness == BITNESS_32
 #if SUPPORTED_PERSONALITIES > 1
-           || personality_wordsize[current_personality] == 4
+           || current_wordsize == 4
 #endif
                )
        {
@@ -87,7 +87,7 @@ sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int spec
 
                rc = umove(tcp, addr, &tv);
                if (rc >= 0) {
-                       if (special && tv.tv_sec == 0) {
+                       if (special) {
                                if (tv.tv_usec == UTIME_NOW)
                                        return stpcpy(buf, "UTIME_NOW");
                                if (tv.tv_usec == UTIME_OMIT)
@@ -101,7 +101,7 @@ sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int spec
 
                rc = umove(tcp, addr, &tv);
                if (rc >= 0) {
-                       if (special && tv.tv_sec == 0) {
+                       if (special) {
                                if (tv.tv_usec == UTIME_NOW)
                                        return stpcpy(buf, "UTIME_NOW");
                                if (tv.tv_usec == UTIME_OMIT)
@@ -135,7 +135,7 @@ sprint_timespec(char *buf, struct tcb *tcp, long addr)
                int rc;
 
 #if SUPPORTED_PERSONALITIES > 1
-               if (personality_wordsize[current_personality] == 4) {
+               if (current_wordsize == 4) {
                        struct timeval32 tv;
 
                        rc = umove(tcp, addr, &tv);
@@ -167,15 +167,6 @@ sys_time(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_stime(struct tcb *tcp)
-{
-       if (exiting(tcp)) {
-               printnum(tcp, tcp->u_arg[0], "%ld");
-       }
-       return 0;
-}
-
 int
 sys_gettimeofday(struct tcb *tcp)
 {
@@ -256,25 +247,30 @@ sys_nanosleep(struct tcb *tcp)
                tprints(", ");
        } else {
                /* Second (returned) timespec is only significant
-                * if syscall was interrupted. We print only its address
-                * on _success_, since kernel doesn't modify its value.
+                * if syscall was interrupted. On success, we print
+                * only its address, since kernel doesn't modify it,
+                * and printing the value may show uninitialized data.
                 */
-               if (is_restart_error(tcp) || !tcp->u_arg[1])
-                       /* Interrupted (or NULL) */
+               switch (tcp->u_error) {
+               default:
+                       /* Not interrupted (slept entire interval) */
+                       if (tcp->u_arg[1]) {
+                               tprintf("%#lx", tcp->u_arg[1]);
+                               break;
+                       }
+                       /* Fall through: print_timespec(NULL) prints "NULL" */
+               case ERESTARTSYS:
+               case ERESTARTNOINTR:
+               case ERESTARTNOHAND:
+               case ERESTART_RESTARTBLOCK:
+                       /* Interrupted */
                        print_timespec(tcp, tcp->u_arg[1]);
-               else
-                       /* Success */
-                       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"   },
-       { 0,            NULL            },
-};
+#include "xlat/itimer_which.h"
 
 static void
 printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
@@ -288,7 +284,7 @@ printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
 
                if (bitness == BITNESS_32
 #if SUPPORTED_PERSONALITIES > 1
-                   || personality_wordsize[current_personality] == 4
+                   || current_wordsize == 4
 #endif
                        )
                {
@@ -328,7 +324,7 @@ int
 sys_getitimer(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(which, tcp->u_arg[0], "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
        } else {
                if (syserror(tcp))
@@ -344,7 +340,7 @@ int
 sys_osf_getitimer(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(which, tcp->u_arg[0], "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
        } else {
                if (syserror(tcp))
@@ -360,7 +356,7 @@ int
 sys_setitimer(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(which, tcp->u_arg[0], "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
                printitv(tcp, tcp->u_arg[1]);
                tprints(", ");
@@ -378,7 +374,7 @@ int
 sys_osf_setitimer(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(which, tcp->u_arg[0], "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
                printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
                tprints(", ");
@@ -392,99 +388,9 @@ sys_osf_setitimer(struct tcb *tcp)
 }
 #endif
 
-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 }
-};
+#include "xlat/adjtimex_modes.h"
+#include "xlat/adjtimex_status.h"
+#include "xlat/adjtimex_state.h"
 
 #if SUPPORTED_PERSONALITIES > 1
 static int
@@ -542,7 +448,7 @@ tprint_timex(struct tcb *tcp, long addr)
        struct timex tx;
 
 #if SUPPORTED_PERSONALITIES > 1
-       if (personality_wordsize[current_personality] == 4)
+       if (current_wordsize == 4)
                return tprint_timex32(tcp, addr);
 #endif
        if (umove(tcp, addr, &tx) < 0)
@@ -604,41 +510,37 @@ sys_adjtimex(struct tcb *tcp)
        return 0;
 }
 
-static const struct xlat clockflags[] = {
-  { TIMER_ABSTIME, "TIMER_ABSTIME" },
-  { 0,             NULL }
-};
+#include "xlat/clockflags.h"
+#include "xlat/clocknames.h"
 
-static const struct xlat clocknames[] = {
-#ifdef CLOCK_REALTIME
-  { CLOCK_REALTIME, "CLOCK_REALTIME" },
-#endif
-#ifdef CLOCK_MONOTONIC
-  { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" },
-#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" },
+static void
+printclockname(int clockid)
+{
+#ifdef CLOCKID_TO_FD
+# include "xlat/cpuclocknames.h"
+
+       if (clockid < 0) {
+               if ((clockid & CLOCKFD_MASK) == CLOCKFD)
+                       tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
+               else {
+                       if(CPUCLOCK_PERTHREAD(clockid))
+                               tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
+                       else
+                               tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
+                       printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
+                       tprints(")");
+               }
+       }
+       else
 #endif
-  { 0, NULL }
-};
+               printxval(clocknames, clockid, "CLOCK_???");
+}
 
 int
 sys_clock_settime(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
                printtv(tcp, tcp->u_arg[1]);
        }
@@ -649,7 +551,7 @@ int
 sys_clock_gettime(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
        } else {
                if (syserror(tcp))
@@ -664,7 +566,7 @@ int
 sys_clock_nanosleep(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
                printflags(clockflags, tcp->u_arg[1], "TIMER_???");
                tprints(", ");
@@ -684,7 +586,7 @@ sys_clock_adjtime(struct tcb *tcp)
 {
        if (exiting(tcp))
                return do_adjtimex(tcp, tcp->u_arg[1]);
-       printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+       printclockname(tcp->u_arg[0]);
        tprints(", ");
        return 0;
 }
@@ -692,13 +594,7 @@ sys_clock_adjtime(struct tcb *tcp)
 #ifndef SIGEV_THREAD_ID
 # define SIGEV_THREAD_ID 4
 #endif
-static const struct xlat sigev_value[] = {
-       { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" },
-       { SIGEV_NONE+1, "SIGEV_NONE" },
-       { SIGEV_THREAD+1, "SIGEV_THREAD" },
-       { SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" },
-       { 0, NULL }
-};
+#include "xlat/sigev_value.h"
 
 #if SUPPORTED_PERSONALITIES > 1
 static void
@@ -725,7 +621,7 @@ printsigevent32(struct tcb *tcp, long arg)
                        tprintf("%s, ", signame(sev.sigev_signo));
                else
                        tprintf("%u, ", sev.sigev_signo);
-               printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???");
+               printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
                tprints(", ");
                if (sev.sigev_notify == SIGEV_THREAD_ID)
                        tprintf("{%d}", sev.un.tid);
@@ -746,7 +642,7 @@ printsigevent(struct tcb *tcp, long arg)
        struct sigevent sev;
 
 #if SUPPORTED_PERSONALITIES > 1
-       if (personality_wordsize[current_personality] == 4) {
+       if (current_wordsize == 4) {
                printsigevent32(tcp, arg);
                return;
        }
@@ -759,13 +655,20 @@ printsigevent(struct tcb *tcp, long arg)
                        tprintf("%s, ", signame(sev.sigev_signo));
                else
                        tprintf("%u, ", sev.sigev_signo);
-               printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???");
+               printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
                tprints(", ");
                if (sev.sigev_notify == SIGEV_THREAD_ID)
+#if defined(HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD)
                        /* _pad[0] is the _tid field which might not be
                           present in the userlevel definition of the
                           struct.  */
                        tprintf("{%d}", sev._sigev_un._pad[0]);
+#elif defined(HAVE_STRUCT_SIGEVENT___PAD)
+                       tprintf("{%d}", sev.__pad[0]);
+#else
+# warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding
+                       tprints("{...}");
+#endif
                else if (sev.sigev_notify == SIGEV_THREAD)
                        tprintf("{%p, %p}", sev.sigev_notify_function,
                                sev.sigev_notify_attributes);
@@ -779,7 +682,7 @@ int
 sys_timer_create(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
                printsigevent(tcp, tcp->u_arg[1]);
                tprints(", ");
@@ -916,10 +819,7 @@ rtc_ioctl(struct tcb *tcp, long code, long arg)
 #define TFD_TIMER_ABSTIME (1 << 0)
 #endif
 
-static const struct xlat timerfdflags[] = {
-       { TFD_TIMER_ABSTIME,    "TFD_TIMER_ABSTIME"     },
-       { 0,                    NULL                    }
-};
+#include "xlat/timerfdflags.h"
 
 int
 sys_timerfd(struct tcb *tcp)
@@ -927,7 +827,7 @@ sys_timerfd(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_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
                printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
                tprints(", ");
@@ -940,7 +840,7 @@ int
 sys_timerfd_create(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
+               printclockname(tcp->u_arg[0]);
                tprints(", ");
                printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
        }