]> granicus.if.org Git - strace/blob - time.c
Convert sigev_value to XLAT form
[strace] / time.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "defs.h"
31 #include <linux/version.h>
32 #include <sys/timex.h>
33 #include <linux/ioctl.h>
34 #include <linux/rtc.h>
35
36 #ifndef UTIME_NOW
37 #define UTIME_NOW ((1l << 30) - 1l)
38 #endif
39 #ifndef UTIME_OMIT
40 #define UTIME_OMIT ((1l << 30) - 2l)
41 #endif
42
43 struct timeval32
44 {
45         u_int32_t tv_sec, tv_usec;
46 };
47
48 static void
49 tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv)
50 {
51         tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec);
52 }
53
54 static void
55 tprint_timeval(struct tcb *tcp, const struct timeval *tv)
56 {
57         tprintf("{%lu, %lu}",
58                 (unsigned long) tv->tv_sec, (unsigned long) tv->tv_usec);
59 }
60
61 void
62 printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
63 {
64         char buf[TIMEVAL_TEXT_BUFSIZE];
65         sprinttv(buf, tcp, addr, bitness, special);
66         tprints(buf);
67 }
68
69 char *
70 sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int special)
71 {
72         int rc;
73
74         if (addr == 0)
75                 return stpcpy(buf, "NULL");
76
77         if (!verbose(tcp))
78                 return buf + sprintf(buf, "%#lx", addr);
79
80         if (bitness == BITNESS_32
81 #if SUPPORTED_PERSONALITIES > 1
82             || current_wordsize == 4
83 #endif
84                 )
85         {
86                 struct timeval32 tv;
87
88                 rc = umove(tcp, addr, &tv);
89                 if (rc >= 0) {
90                         if (special && tv.tv_sec == 0) {
91                                 if (tv.tv_usec == UTIME_NOW)
92                                         return stpcpy(buf, "UTIME_NOW");
93                                 if (tv.tv_usec == UTIME_OMIT)
94                                         return stpcpy(buf, "UTIME_OMIT");
95                         }
96                         return buf + sprintf(buf, "{%u, %u}",
97                                 tv.tv_sec, tv.tv_usec);
98                 }
99         } else {
100                 struct timeval tv;
101
102                 rc = umove(tcp, addr, &tv);
103                 if (rc >= 0) {
104                         if (special && tv.tv_sec == 0) {
105                                 if (tv.tv_usec == UTIME_NOW)
106                                         return stpcpy(buf, "UTIME_NOW");
107                                 if (tv.tv_usec == UTIME_OMIT)
108                                         return stpcpy(buf, "UTIME_OMIT");
109                         }
110                         return buf + sprintf(buf, "{%lu, %lu}",
111                                 (unsigned long) tv.tv_sec,
112                                 (unsigned long) tv.tv_usec);
113                 }
114         }
115
116         return stpcpy(buf, "{...}");
117 }
118
119 void
120 print_timespec(struct tcb *tcp, long addr)
121 {
122         char buf[TIMESPEC_TEXT_BUFSIZE];
123         sprint_timespec(buf, tcp, addr);
124         tprints(buf);
125 }
126
127 void
128 sprint_timespec(char *buf, struct tcb *tcp, long addr)
129 {
130         if (addr == 0)
131                 strcpy(buf, "NULL");
132         else if (!verbose(tcp))
133                 sprintf(buf, "%#lx", addr);
134         else {
135                 int rc;
136
137 #if SUPPORTED_PERSONALITIES > 1
138                 if (current_wordsize == 4) {
139                         struct timeval32 tv;
140
141                         rc = umove(tcp, addr, &tv);
142                         if (rc >= 0)
143                                 sprintf(buf, "{%u, %u}",
144                                         tv.tv_sec, tv.tv_usec);
145                 } else
146 #endif
147                 {
148                         struct timespec ts;
149
150                         rc = umove(tcp, addr, &ts);
151                         if (rc >= 0)
152                                 sprintf(buf, "{%lu, %lu}",
153                                         (unsigned long) ts.tv_sec,
154                                         (unsigned long) ts.tv_nsec);
155                 }
156                 if (rc < 0)
157                         strcpy(buf, "{...}");
158         }
159 }
160
161 int
162 sys_time(struct tcb *tcp)
163 {
164         if (exiting(tcp)) {
165                 printnum(tcp, tcp->u_arg[0], "%ld");
166         }
167         return 0;
168 }
169
170 int
171 sys_stime(struct tcb *tcp)
172 {
173         if (exiting(tcp)) {
174                 printnum(tcp, tcp->u_arg[0], "%ld");
175         }
176         return 0;
177 }
178
179 int
180 sys_gettimeofday(struct tcb *tcp)
181 {
182         if (exiting(tcp)) {
183                 if (syserror(tcp)) {
184                         tprintf("%#lx, %#lx",
185                                 tcp->u_arg[0], tcp->u_arg[1]);
186                         return 0;
187                 }
188                 printtv(tcp, tcp->u_arg[0]);
189                 tprints(", ");
190                 printtv(tcp, tcp->u_arg[1]);
191         }
192         return 0;
193 }
194
195 #ifdef ALPHA
196 int
197 sys_osf_gettimeofday(struct tcb *tcp)
198 {
199         if (exiting(tcp)) {
200                 if (syserror(tcp)) {
201                         tprintf("%#lx, %#lx", tcp->u_arg[0], tcp->u_arg[1]);
202                         return 0;
203                 }
204                 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
205                 tprints(", ");
206                 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
207         }
208         return 0;
209 }
210 #endif
211
212 int
213 sys_settimeofday(struct tcb *tcp)
214 {
215         if (entering(tcp)) {
216                 printtv(tcp, tcp->u_arg[0]);
217                 tprints(", ");
218                 printtv(tcp, tcp->u_arg[1]);
219         }
220         return 0;
221 }
222
223 #ifdef ALPHA
224 int
225 sys_osf_settimeofday(struct tcb *tcp)
226 {
227         if (entering(tcp)) {
228                 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
229                 tprints(", ");
230                 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
231         }
232         return 0;
233 }
234 #endif
235
236 int
237 sys_adjtime(struct tcb *tcp)
238 {
239         if (entering(tcp)) {
240                 printtv(tcp, tcp->u_arg[0]);
241                 tprints(", ");
242         } else {
243                 if (syserror(tcp))
244                         tprintf("%#lx", tcp->u_arg[1]);
245                 else
246                         printtv(tcp, tcp->u_arg[1]);
247         }
248         return 0;
249 }
250
251 int
252 sys_nanosleep(struct tcb *tcp)
253 {
254         if (entering(tcp)) {
255                 print_timespec(tcp, tcp->u_arg[0]);
256                 tprints(", ");
257         } else {
258                 /* Second (returned) timespec is only significant
259                  * if syscall was interrupted. On success, we print
260                  * only its address, since kernel doesn't modify it,
261                  * and printing the value may show uninitialized data.
262                  */
263                 switch (tcp->u_error) {
264                 default:
265                         /* Not interrupted (slept entire interval) */
266                         if (tcp->u_arg[1]) {
267                                 tprintf("%#lx", tcp->u_arg[1]);
268                                 break;
269                         }
270                         /* Fall through: print_timespec(NULL) prints "NULL" */
271                 case ERESTARTSYS:
272                 case ERESTARTNOINTR:
273                 case ERESTARTNOHAND:
274                 case ERESTART_RESTARTBLOCK:
275                         /* Interrupted */
276                         print_timespec(tcp, tcp->u_arg[1]);
277                 }
278         }
279         return 0;
280 }
281
282 static const struct xlat which[] = {
283         XLAT(ITIMER_REAL),
284         XLAT(ITIMER_VIRTUAL),
285         XLAT(ITIMER_PROF),
286         { 0,            NULL            },
287 };
288
289 static void
290 printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
291 {
292         if (addr == 0)
293                 tprints("NULL");
294         else if (!verbose(tcp))
295                 tprintf("%#lx", addr);
296         else {
297                 int rc;
298
299                 if (bitness == BITNESS_32
300 #if SUPPORTED_PERSONALITIES > 1
301                     || current_wordsize == 4
302 #endif
303                         )
304                 {
305                         struct {
306                                 struct timeval32 it_interval, it_value;
307                         } itv;
308
309                         rc = umove(tcp, addr, &itv);
310                         if (rc >= 0) {
311                                 tprints("{it_interval=");
312                                 tprint_timeval32(tcp, &itv.it_interval);
313                                 tprints(", it_value=");
314                                 tprint_timeval32(tcp, &itv.it_value);
315                                 tprints("}");
316                         }
317                 } else {
318                         struct itimerval itv;
319
320                         rc = umove(tcp, addr, &itv);
321                         if (rc >= 0) {
322                                 tprints("{it_interval=");
323                                 tprint_timeval(tcp, &itv.it_interval);
324                                 tprints(", it_value=");
325                                 tprint_timeval(tcp, &itv.it_value);
326                                 tprints("}");
327                         }
328                 }
329                 if (rc < 0)
330                         tprints("{...}");
331         }
332 }
333
334 #define printitv(tcp, addr)     \
335         printitv_bitness((tcp), (addr), BITNESS_CURRENT)
336
337 int
338 sys_getitimer(struct tcb *tcp)
339 {
340         if (entering(tcp)) {
341                 printxval(which, tcp->u_arg[0], "ITIMER_???");
342                 tprints(", ");
343         } else {
344                 if (syserror(tcp))
345                         tprintf("%#lx", tcp->u_arg[1]);
346                 else
347                         printitv(tcp, tcp->u_arg[1]);
348         }
349         return 0;
350 }
351
352 #ifdef ALPHA
353 int
354 sys_osf_getitimer(struct tcb *tcp)
355 {
356         if (entering(tcp)) {
357                 printxval(which, tcp->u_arg[0], "ITIMER_???");
358                 tprints(", ");
359         } else {
360                 if (syserror(tcp))
361                         tprintf("%#lx", tcp->u_arg[1]);
362                 else
363                         printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
364         }
365         return 0;
366 }
367 #endif
368
369 int
370 sys_setitimer(struct tcb *tcp)
371 {
372         if (entering(tcp)) {
373                 printxval(which, tcp->u_arg[0], "ITIMER_???");
374                 tprints(", ");
375                 printitv(tcp, tcp->u_arg[1]);
376                 tprints(", ");
377         } else {
378                 if (syserror(tcp))
379                         tprintf("%#lx", tcp->u_arg[2]);
380                 else
381                         printitv(tcp, tcp->u_arg[2]);
382         }
383         return 0;
384 }
385
386 #ifdef ALPHA
387 int
388 sys_osf_setitimer(struct tcb *tcp)
389 {
390         if (entering(tcp)) {
391                 printxval(which, tcp->u_arg[0], "ITIMER_???");
392                 tprints(", ");
393                 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
394                 tprints(", ");
395         } else {
396                 if (syserror(tcp))
397                         tprintf("%#lx", tcp->u_arg[2]);
398                 else
399                         printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32);
400         }
401         return 0;
402 }
403 #endif
404
405 static const struct xlat adjtimex_modes[] = {
406         XLAT(0),
407 #ifdef ADJ_OFFSET
408         XLAT(ADJ_OFFSET),
409 #endif
410 #ifdef ADJ_FREQUENCY
411         XLAT(ADJ_FREQUENCY),
412 #endif
413 #ifdef ADJ_MAXERROR
414         XLAT(ADJ_MAXERROR),
415 #endif
416 #ifdef ADJ_ESTERROR
417         XLAT(ADJ_ESTERROR),
418 #endif
419 #ifdef ADJ_STATUS
420         XLAT(ADJ_STATUS),
421 #endif
422 #ifdef ADJ_TIMECONST
423         XLAT(ADJ_TIMECONST),
424 #endif
425 #ifdef ADJ_TAI
426         XLAT(ADJ_TAI),
427 #endif
428 #ifdef ADJ_SETOFFSET
429         XLAT(ADJ_SETOFFSET),
430 #endif
431 #ifdef ADJ_MICRO
432         XLAT(ADJ_MICRO),
433 #endif
434 #ifdef ADJ_NANO
435         XLAT(ADJ_NANO),
436 #endif
437 #ifdef ADJ_TICK
438         XLAT(ADJ_TICK),
439 #endif
440 #ifdef ADJ_OFFSET_SINGLESHOT
441         XLAT(ADJ_OFFSET_SINGLESHOT),
442 #endif
443 #ifdef ADJ_OFFSET_SS_READ
444         XLAT(ADJ_OFFSET_SS_READ),
445 #endif
446         { 0,            NULL                    }
447 };
448
449 static const struct xlat adjtimex_status[] = {
450 #ifdef STA_PLL
451         XLAT(STA_PLL),
452 #endif
453 #ifdef STA_PPSFREQ
454         XLAT(STA_PPSFREQ),
455 #endif
456 #ifdef STA_PPSTIME
457         XLAT(STA_PPSTIME),
458 #endif
459 #ifdef STA_FLL
460         XLAT(STA_FLL),
461 #endif
462 #ifdef STA_INS
463         XLAT(STA_INS),
464 #endif
465 #ifdef STA_DEL
466         XLAT(STA_DEL),
467 #endif
468 #ifdef STA_UNSYNC
469         XLAT(STA_UNSYNC),
470 #endif
471 #ifdef STA_FREQHOLD
472         XLAT(STA_FREQHOLD),
473 #endif
474 #ifdef STA_PPSSIGNAL
475         XLAT(STA_PPSSIGNAL),
476 #endif
477 #ifdef STA_PPSJITTER
478         XLAT(STA_PPSJITTER),
479 #endif
480 #ifdef STA_PPSWANDER
481         XLAT(STA_PPSWANDER),
482 #endif
483 #ifdef STA_PPSERROR
484         XLAT(STA_PPSERROR),
485 #endif
486 #ifdef STA_CLOCKERR
487         XLAT(STA_CLOCKERR),
488 #endif
489 #ifdef STA_NANO
490         XLAT(STA_NANO),
491 #endif
492 #ifdef STA_MODE
493         XLAT(STA_MODE),
494 #endif
495 #ifdef STA_CLK
496         XLAT(STA_CLK),
497 #endif
498         { 0,            NULL            }
499 };
500
501 static const struct xlat adjtimex_state[] = {
502 #ifdef TIME_OK
503         XLAT(TIME_OK),
504 #endif
505 #ifdef TIME_INS
506         XLAT(TIME_INS),
507 #endif
508 #ifdef TIME_DEL
509         XLAT(TIME_DEL),
510 #endif
511 #ifdef TIME_OOP
512         XLAT(TIME_OOP),
513 #endif
514 #ifdef TIME_WAIT
515         XLAT(TIME_WAIT),
516 #endif
517 #ifdef TIME_ERROR
518         XLAT(TIME_ERROR),
519 #endif
520         { 0,            NULL            }
521 };
522
523 #if SUPPORTED_PERSONALITIES > 1
524 static int
525 tprint_timex32(struct tcb *tcp, long addr)
526 {
527         struct {
528                 unsigned int modes;
529                 int     offset;
530                 int     freq;
531                 int     maxerror;
532                 int     esterror;
533                 int     status;
534                 int     constant;
535                 int     precision;
536                 int     tolerance;
537                 struct timeval32 time;
538                 int     tick;
539                 int     ppsfreq;
540                 int     jitter;
541                 int     shift;
542                 int     stabil;
543                 int     jitcnt;
544                 int     calcnt;
545                 int     errcnt;
546                 int     stbcnt;
547         } tx;
548
549         if (umove(tcp, addr, &tx) < 0)
550                 return -1;
551
552         tprints("{modes=");
553         printflags(adjtimex_modes, tx.modes, "ADJ_???");
554         tprintf(", offset=%d, freq=%d, maxerror=%d, ",
555                 tx.offset, tx.freq, tx.maxerror);
556         tprintf("esterror=%u, status=", tx.esterror);
557         printflags(adjtimex_status, tx.status, "STA_???");
558         tprintf(", constant=%d, precision=%u, ",
559                 tx.constant, tx.precision);
560         tprintf("tolerance=%d, time=", tx.tolerance);
561         tprint_timeval32(tcp, &tx.time);
562         tprintf(", tick=%d, ppsfreq=%d, jitter=%d",
563                 tx.tick, tx.ppsfreq, tx.jitter);
564         tprintf(", shift=%d, stabil=%d, jitcnt=%d",
565                 tx.shift, tx.stabil, tx.jitcnt);
566         tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d",
567                 tx.calcnt, tx.errcnt, tx.stbcnt);
568         tprints("}");
569         return 0;
570 }
571 #endif /* SUPPORTED_PERSONALITIES > 1 */
572
573 static int
574 tprint_timex(struct tcb *tcp, long addr)
575 {
576         struct timex tx;
577
578 #if SUPPORTED_PERSONALITIES > 1
579         if (current_wordsize == 4)
580                 return tprint_timex32(tcp, addr);
581 #endif
582         if (umove(tcp, addr, &tx) < 0)
583                 return -1;
584
585 #if LINUX_VERSION_CODE < 66332
586         tprintf("{mode=%d, offset=%ld, frequency=%ld, ",
587                 tx.mode, tx.offset, tx.frequency);
588         tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
589                 tx.maxerror, tx.esterror, tx.status);
590         tprintf("time_constant=%ld, precision=%lu, ",
591                 tx.time_constant, tx.precision);
592         tprintf("tolerance=%ld, time=", tx.tolerance);
593         tprint_timeval(tcp, &tx.time);
594 #else
595         tprints("{modes=");
596         printflags(adjtimex_modes, tx.modes, "ADJ_???");
597         tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ",
598                 (long) tx.offset, (long) tx.freq, (long) tx.maxerror);
599         tprintf("esterror=%lu, status=", (long) tx.esterror);
600         printflags(adjtimex_status, tx.status, "STA_???");
601         tprintf(", constant=%ld, precision=%lu, ",
602                 (long) tx.constant, (long) tx.precision);
603         tprintf("tolerance=%ld, time=", (long) tx.tolerance);
604         tprint_timeval(tcp, &tx.time);
605         tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld",
606                 (long) tx.tick, (long) tx.ppsfreq, (long) tx.jitter);
607         tprintf(", shift=%d, stabil=%ld, jitcnt=%ld",
608                 tx.shift, (long) tx.stabil, (long) tx.jitcnt);
609         tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld",
610                 (long) tx.calcnt, (long) tx.errcnt, (long) tx.stbcnt);
611 #endif
612         tprints("}");
613         return 0;
614 }
615
616 static int
617 do_adjtimex(struct tcb *tcp, long addr)
618 {
619         if (addr == 0)
620                 tprints("NULL");
621         else if (syserror(tcp) || !verbose(tcp))
622                 tprintf("%#lx", addr);
623         else if (tprint_timex(tcp, addr) < 0)
624                 tprints("{...}");
625         if (syserror(tcp))
626                 return 0;
627         tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
628         if (tcp->auxstr)
629                 return RVAL_STR;
630         return 0;
631 }
632
633 int
634 sys_adjtimex(struct tcb *tcp)
635 {
636         if (exiting(tcp))
637                 return do_adjtimex(tcp, tcp->u_arg[0]);
638         return 0;
639 }
640
641 static const struct xlat clockflags[] = {
642         XLAT(TIMER_ABSTIME),
643         { 0,                    NULL            }
644 };
645
646 static const struct xlat clocknames[] = {
647 #ifdef CLOCK_REALTIME
648         XLAT(CLOCK_REALTIME),
649 #endif
650 #ifdef CLOCK_MONOTONIC
651         XLAT(CLOCK_MONOTONIC),
652 #endif
653 #ifdef CLOCK_PROCESS_CPUTIME_ID
654         XLAT(CLOCK_PROCESS_CPUTIME_ID),
655 #endif
656 #ifdef CLOCK_THREAD_CPUTIME_ID
657         XLAT(CLOCK_THREAD_CPUTIME_ID),
658 #endif
659 #ifdef CLOCK_MONOTONIC_RAW
660         XLAT(CLOCK_MONOTONIC_RAW),
661 #endif
662 #ifdef CLOCK_REALTIME_COARSE
663         XLAT(CLOCK_REALTIME_COARSE),
664 #endif
665 #ifdef CLOCK_MONOTONIC_COARSE
666         XLAT(CLOCK_MONOTONIC_COARSE),
667 #endif
668         { 0,                            NULL }
669 };
670
671 #ifdef CLOCKID_TO_FD
672 static const struct xlat cpuclocknames[] = {
673         XLAT(CPUCLOCK_PROF),
674         XLAT(CPUCLOCK_VIRT),
675         XLAT(CPUCLOCK_SCHED),
676         { 0, NULL }
677 };
678 #endif
679
680 static void
681 printclockname(int clockid)
682 {
683 #ifdef CLOCKID_TO_FD
684         if (clockid < 0) {
685                 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
686                         tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
687                 else {
688                         if(CPUCLOCK_PERTHREAD(clockid))
689                                 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
690                         else
691                                 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
692                         printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
693                         tprints(")");
694                 }
695         }
696         else
697 #endif
698                 printxval(clocknames, clockid, "CLOCK_???");
699 }
700
701 int
702 sys_clock_settime(struct tcb *tcp)
703 {
704         if (entering(tcp)) {
705                 printclockname(tcp->u_arg[0]);
706                 tprints(", ");
707                 printtv(tcp, tcp->u_arg[1]);
708         }
709         return 0;
710 }
711
712 int
713 sys_clock_gettime(struct tcb *tcp)
714 {
715         if (entering(tcp)) {
716                 printclockname(tcp->u_arg[0]);
717                 tprints(", ");
718         } else {
719                 if (syserror(tcp))
720                         tprintf("%#lx", tcp->u_arg[1]);
721                 else
722                         printtv(tcp, tcp->u_arg[1]);
723         }
724         return 0;
725 }
726
727 int
728 sys_clock_nanosleep(struct tcb *tcp)
729 {
730         if (entering(tcp)) {
731                 printclockname(tcp->u_arg[0]);
732                 tprints(", ");
733                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
734                 tprints(", ");
735                 printtv(tcp, tcp->u_arg[2]);
736                 tprints(", ");
737         } else {
738                 if (syserror(tcp))
739                         tprintf("%#lx", tcp->u_arg[3]);
740                 else
741                         printtv(tcp, tcp->u_arg[3]);
742         }
743         return 0;
744 }
745
746 int
747 sys_clock_adjtime(struct tcb *tcp)
748 {
749         if (exiting(tcp))
750                 return do_adjtimex(tcp, tcp->u_arg[1]);
751         printclockname(tcp->u_arg[0]);
752         tprints(", ");
753         return 0;
754 }
755
756 #ifndef SIGEV_THREAD_ID
757 # define SIGEV_THREAD_ID 4
758 #endif
759 static const struct xlat sigev_value[] = {
760         XLAT(SIGEV_SIGNAL),
761         XLAT(SIGEV_NONE),
762         XLAT(SIGEV_THREAD),
763         XLAT(SIGEV_THREAD_ID),
764         { 0, NULL }
765 };
766
767 #if SUPPORTED_PERSONALITIES > 1
768 static void
769 printsigevent32(struct tcb *tcp, long arg)
770 {
771         struct {
772                 int     sigev_value;
773                 int     sigev_signo;
774                 int     sigev_notify;
775
776                 union {
777                         int     tid;
778                         struct {
779                                 int     function, attribute;
780                         } thread;
781                 } un;
782         } sev;
783
784         if (umove(tcp, arg, &sev) < 0)
785                 tprints("{...}");
786         else {
787                 tprintf("{%#x, ", sev.sigev_value);
788                 if (sev.sigev_notify == SIGEV_SIGNAL)
789                         tprintf("%s, ", signame(sev.sigev_signo));
790                 else
791                         tprintf("%u, ", sev.sigev_signo);
792                 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
793                 tprints(", ");
794                 if (sev.sigev_notify == SIGEV_THREAD_ID)
795                         tprintf("{%d}", sev.un.tid);
796                 else if (sev.sigev_notify == SIGEV_THREAD)
797                         tprintf("{%#x, %#x}",
798                                 sev.un.thread.function,
799                                 sev.un.thread.attribute);
800                 else
801                         tprints("{...}");
802                 tprints("}");
803         }
804 }
805 #endif
806
807 void
808 printsigevent(struct tcb *tcp, long arg)
809 {
810         struct sigevent sev;
811
812 #if SUPPORTED_PERSONALITIES > 1
813         if (current_wordsize == 4) {
814                 printsigevent32(tcp, arg);
815                 return;
816         }
817 #endif
818         if (umove(tcp, arg, &sev) < 0)
819                 tprints("{...}");
820         else {
821                 tprintf("{%p, ", sev.sigev_value.sival_ptr);
822                 if (sev.sigev_notify == SIGEV_SIGNAL)
823                         tprintf("%s, ", signame(sev.sigev_signo));
824                 else
825                         tprintf("%u, ", sev.sigev_signo);
826                 printxval(sigev_value, sev.sigev_notify, "SIGEV_???");
827                 tprints(", ");
828                 if (sev.sigev_notify == SIGEV_THREAD_ID)
829 #if defined(HAVE_STRUCT_SIGEVENT__SIGEV_UN__PAD)
830                         /* _pad[0] is the _tid field which might not be
831                            present in the userlevel definition of the
832                            struct.  */
833                         tprintf("{%d}", sev._sigev_un._pad[0]);
834 #elif defined(HAVE_STRUCT_SIGEVENT___PAD)
835                         tprintf("{%d}", sev.__pad[0]);
836 #else
837 # warning unfamiliar struct sigevent => incomplete SIGEV_THREAD_ID decoding
838                         tprints("{...}");
839 #endif
840                 else if (sev.sigev_notify == SIGEV_THREAD)
841                         tprintf("{%p, %p}", sev.sigev_notify_function,
842                                 sev.sigev_notify_attributes);
843                 else
844                         tprints("{...}");
845                 tprints("}");
846         }
847 }
848
849 int
850 sys_timer_create(struct tcb *tcp)
851 {
852         if (entering(tcp)) {
853                 printclockname(tcp->u_arg[0]);
854                 tprints(", ");
855                 printsigevent(tcp, tcp->u_arg[1]);
856                 tprints(", ");
857         } else {
858                 int timer_id;
859
860                 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &timer_id) < 0)
861                         tprintf("%#lx", tcp->u_arg[2]);
862                 else
863                         tprintf("{%d}", timer_id);
864         }
865         return 0;
866 }
867
868 int
869 sys_timer_settime(struct tcb *tcp)
870 {
871         if (entering(tcp)) {
872                 tprintf("%#lx, ", tcp->u_arg[0]);
873                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
874                 tprints(", ");
875                 printitv(tcp, tcp->u_arg[2]);
876                 tprints(", ");
877         } else {
878                 if (syserror(tcp))
879                         tprintf("%#lx", tcp->u_arg[3]);
880                 else
881                         printitv(tcp, tcp->u_arg[3]);
882         }
883         return 0;
884 }
885
886 int
887 sys_timer_gettime(struct tcb *tcp)
888 {
889         if (entering(tcp)) {
890                 tprintf("%#lx, ", tcp->u_arg[0]);
891         } else {
892                 if (syserror(tcp))
893                         tprintf("%#lx", tcp->u_arg[1]);
894                 else
895                         printitv(tcp, tcp->u_arg[1]);
896         }
897         return 0;
898 }
899
900 static void
901 print_rtc(struct tcb *tcp, const struct rtc_time *rt)
902 {
903         tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, "
904                 "tm_mday=%d, tm_mon=%d, tm_year=%d, ",
905                 rt->tm_sec, rt->tm_min, rt->tm_hour,
906                 rt->tm_mday, rt->tm_mon, rt->tm_year);
907         if (!abbrev(tcp))
908                 tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
909                         rt->tm_wday, rt->tm_yday, rt->tm_isdst);
910         else
911                 tprints("...}");
912 }
913
914 int
915 rtc_ioctl(struct tcb *tcp, long code, long arg)
916 {
917         switch (code) {
918         case RTC_ALM_SET:
919         case RTC_SET_TIME:
920                 if (entering(tcp)) {
921                         struct rtc_time rt;
922                         if (umove(tcp, arg, &rt) < 0)
923                                 tprintf(", %#lx", arg);
924                         else {
925                                 tprints(", ");
926                                 print_rtc(tcp, &rt);
927                         }
928                 }
929                 break;
930         case RTC_ALM_READ:
931         case RTC_RD_TIME:
932                 if (exiting(tcp)) {
933                         struct rtc_time rt;
934                         if (syserror(tcp) || umove(tcp, arg, &rt) < 0)
935                                 tprintf(", %#lx", arg);
936                         else {
937                                 tprints(", ");
938                                 print_rtc(tcp, &rt);
939                         }
940                 }
941                 break;
942         case RTC_IRQP_SET:
943         case RTC_EPOCH_SET:
944                 if (entering(tcp))
945                         tprintf(", %lu", arg);
946                 break;
947         case RTC_IRQP_READ:
948         case RTC_EPOCH_READ:
949                 if (exiting(tcp))
950                         tprintf(", %lu", arg);
951                 break;
952         case RTC_WKALM_SET:
953                 if (entering(tcp)) {
954                         struct rtc_wkalrm wk;
955                         if (umove(tcp, arg, &wk) < 0)
956                                 tprintf(", %#lx", arg);
957                         else {
958                                 tprintf(", {enabled=%d, pending=%d, ",
959                                         wk.enabled, wk.pending);
960                                 print_rtc(tcp, &wk.time);
961                                 tprints("}");
962                         }
963                 }
964                 break;
965         case RTC_WKALM_RD:
966                 if (exiting(tcp)) {
967                         struct rtc_wkalrm wk;
968                         if (syserror(tcp) || umove(tcp, arg, &wk) < 0)
969                                 tprintf(", %#lx", arg);
970                         else {
971                                 tprintf(", {enabled=%d, pending=%d, ",
972                                         wk.enabled, wk.pending);
973                                 print_rtc(tcp, &wk.time);
974                                 tprints("}");
975                         }
976                 }
977                 break;
978         default:
979                 if (entering(tcp))
980                         tprintf(", %#lx", arg);
981                 break;
982         }
983         return 1;
984 }
985
986 #ifndef TFD_TIMER_ABSTIME
987 #define TFD_TIMER_ABSTIME (1 << 0)
988 #endif
989
990 static const struct xlat timerfdflags[] = {
991         XLAT(TFD_TIMER_ABSTIME),
992         { 0,                    NULL                    }
993 };
994
995 int
996 sys_timerfd(struct tcb *tcp)
997 {
998         if (entering(tcp)) {
999                 /* It does not matter that the kernel uses itimerspec.  */
1000                 tprintf("%ld, ", tcp->u_arg[0]);
1001                 printclockname(tcp->u_arg[0]);
1002                 tprints(", ");
1003                 printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
1004                 tprints(", ");
1005                 printitv(tcp, tcp->u_arg[3]);
1006         }
1007         return 0;
1008 }
1009
1010 int
1011 sys_timerfd_create(struct tcb *tcp)
1012 {
1013         if (entering(tcp)) {
1014                 printclockname(tcp->u_arg[0]);
1015                 tprints(", ");
1016                 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
1017         }
1018         return 0;
1019 }
1020
1021 int
1022 sys_timerfd_settime(struct tcb *tcp)
1023 {
1024         if (entering(tcp)) {
1025                 printfd(tcp, tcp->u_arg[0]);
1026                 tprints(", ");
1027                 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
1028                 tprints(", ");
1029                 printitv(tcp, tcp->u_arg[2]);
1030                 tprints(", ");
1031                 printitv(tcp, tcp->u_arg[3]);
1032         }
1033         return 0;
1034 }
1035
1036 int
1037 sys_timerfd_gettime(struct tcb *tcp)
1038 {
1039         if (entering(tcp)) {
1040                 printfd(tcp, tcp->u_arg[0]);
1041                 tprints(", ");
1042                 printitv(tcp, tcp->u_arg[1]);
1043         }
1044         return 0;
1045 }