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