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