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