blob: af68eeeb3c2c22ce3fc0b379f538536fb7bf3d4e [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkermand856b992000-10-13 12:47:12 +000036#include <sys/timex.h>
Roland McGrathd83c50b2004-10-06 22:27:43 +000037#include <linux/ioctl.h>
38#include <linux/rtc.h>
Roland McGrath6afc5652007-07-24 01:57:11 +000039
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
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000046#endif /* LINUX */
47
Dmitry V. Levina7945a32006-12-13 17:10:11 +000048struct timeval32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000049{
Dmitry V. Levina7945a32006-12-13 17:10:11 +000050 u_int32_t tv_sec, tv_usec;
51};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000052
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000053static void
54tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv)
55{
56 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec);
57}
58
59static void
60tprint_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
Dmitry V. Levina7945a32006-12-13 17:10:11 +000066void
Roland McGrath6afc5652007-07-24 01:57:11 +000067printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
Dmitry V. Levina7945a32006-12-13 17:10:11 +000068{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000069 if (addr == 0)
70 tprintf("NULL");
71 else if (!verbose(tcp))
72 tprintf("%#lx", addr);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000073 else
Dmitry V. Levina7945a32006-12-13 17:10:11 +000074 {
75 int rc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076
Dmitry V. Levina7945a32006-12-13 17:10:11 +000077 if (bitness == BITNESS_32
78#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
79 || personality_wordsize[current_personality] == 4
80#endif
81 )
82 {
83 struct timeval32 tv;
84
Roland McGrath6afc5652007-07-24 01:57:11 +000085 if ((rc = umove(tcp, addr, &tv)) >= 0) {
Roland McGrath41383392007-07-24 01:58:52 +000086 if (special && tv.tv_sec == 0 &&
87 tv.tv_usec == UTIME_NOW)
Roland McGrath6afc5652007-07-24 01:57:11 +000088 tprintf("UTIME_NOW");
Roland McGrath41383392007-07-24 01:58:52 +000089 else if (special && tv.tv_sec == 0 &&
90 tv.tv_usec == UTIME_OMIT)
Roland McGrath6afc5652007-07-24 01:57:11 +000091 tprintf("UTIME_OMIT");
92 else
93 tprint_timeval32(tcp, &tv);
94 }
Dmitry V. Levina7945a32006-12-13 17:10:11 +000095 } else
96 {
97 struct timeval tv;
98
Roland McGrath6afc5652007-07-24 01:57:11 +000099 if ((rc = umove(tcp, addr, &tv)) >= 0) {
Roland McGrath41383392007-07-24 01:58:52 +0000100 if (special && tv.tv_sec == 0 &&
101 tv.tv_usec == UTIME_NOW)
Roland McGrath6afc5652007-07-24 01:57:11 +0000102 tprintf("UTIME_NOW");
Roland McGrath41383392007-07-24 01:58:52 +0000103 else if (special && tv.tv_sec == 0 &&
104 tv.tv_usec == UTIME_OMIT)
Roland McGrath6afc5652007-07-24 01:57:11 +0000105 tprintf("UTIME_OMIT");
106 else
107 tprint_timeval(tcp, &tv);
108 }
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000109 }
110
111 if (rc < 0)
112 tprintf("{...}");
113 }
114}
Wichert Akkerman221f54f1999-11-18 17:26:45 +0000115
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000116void
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000117sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000118{
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000119 if (addr == 0)
120 strcpy(buf, "NULL");
121 else if (!verbose(tcp))
122 sprintf(buf, "%#lx", addr);
123 else
124 {
125 int rc;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000126
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000127 if (bitness == BITNESS_32
128#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
129 || personality_wordsize[current_personality] == 4
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000130#endif
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000131 )
132 {
133 struct timeval32 tv;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000134
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000135 if ((rc = umove(tcp, addr, &tv)) >= 0)
136 sprintf(buf, "{%u, %u}",
137 tv.tv_sec, tv.tv_usec);
138 } else
139 {
140 struct timeval tv;
141
142 if ((rc = umove(tcp, addr, &tv)) >= 0)
143 sprintf(buf, "{%lu, %lu}",
144 (unsigned long) tv.tv_sec,
145 (unsigned long) tv.tv_usec);
146 }
147
148 if (rc < 0)
149 strcpy(buf, "{...}");
150 }
151}
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000152
Roland McGrath6bc09da2007-11-01 21:50:54 +0000153void print_timespec (struct tcb *tcp, long addr)
154{
155 if (addr == 0)
156 tprintf("NULL");
157 else if (!verbose(tcp))
158 tprintf("%#lx", addr);
159 else {
160 int rc;
161
162#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
163 if (personality_wordsize[current_personality] == 4)
164 {
165 struct timeval32 tv;
166
167 if ((rc = umove(tcp, addr, &tv)) >= 0)
168 tprintf("{%u, %u}",
169 tv.tv_sec, tv.tv_usec);
170 } else
171 {
172#endif
173 struct timespec ts;
174
175 if ((rc = umove(tcp, addr, &ts)) >= 0)
176 tprintf("{%lu, %lu}",
177 (unsigned long) ts.tv_sec,
178 (unsigned long) ts.tv_nsec);
179#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
180 }
181#endif
182
183 if (rc < 0)
184 tprintf("{...}");
185 }
186}
187
188void 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 {
200 struct timeval32 tv;
201
202 if ((rc = umove(tcp, addr, &tv)) >= 0)
203 sprintf(buf, "{%u, %u}",
204 tv.tv_sec, tv.tv_usec);
205 } else
206 {
207#endif
208 struct timespec ts;
209
210 if ((rc = umove(tcp, addr, &ts)) >= 0)
211 sprintf(buf, "{%lu, %lu}",
212 (unsigned long) ts.tv_sec,
213 (unsigned long) ts.tv_nsec);
214#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
215 }
216#endif
217
218 if (rc < 0)
219 strcpy(buf, "{...}");
220 }
221}
222
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223int
224sys_time(tcp)
225struct tcb *tcp;
226{
227 if (exiting(tcp)) {
228#ifndef SVR4
229 printnum(tcp, tcp->u_arg[0], "%ld");
230#endif /* SVR4 */
231 }
232 return 0;
233}
234
235int
236sys_stime(tcp)
237struct tcb *tcp;
238{
239 if (exiting(tcp)) {
240 printnum(tcp, tcp->u_arg[0], "%ld");
241 }
242 return 0;
243}
244
245int
246sys_gettimeofday(tcp)
247struct tcb *tcp;
248{
249 if (exiting(tcp)) {
250 if (syserror(tcp)) {
251 tprintf("%#lx, %#lx",
252 tcp->u_arg[0], tcp->u_arg[1]);
253 return 0;
254 }
255 printtv(tcp, tcp->u_arg[0]);
256#ifndef SVR4
257 tprintf(", ");
258 printtv(tcp, tcp->u_arg[1]);
259#endif /* !SVR4 */
260 }
261 return 0;
262}
263
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000264
265#ifdef ALPHA
266int
267sys_osf_gettimeofday(tcp)
268struct tcb *tcp;
269{
270 if (exiting(tcp)) {
271 if (syserror(tcp)) {
272 tprintf("%#lx, %#lx",
273 tcp->u_arg[0], tcp->u_arg[1]);
274 return 0;
275 }
Roland McGrath6afc5652007-07-24 01:57:11 +0000276 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000277#ifndef SVR4
278 tprintf(", ");
Roland McGrath6afc5652007-07-24 01:57:11 +0000279 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000280#endif /* !SVR4 */
281 }
282 return 0;
283}
284#endif
285
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000286int
287sys_settimeofday(tcp)
288struct tcb *tcp;
289{
290 if (entering(tcp)) {
291 printtv(tcp, tcp->u_arg[0]);
292#ifndef SVR4
293 tprintf(", ");
294 printtv(tcp, tcp->u_arg[1]);
295#endif /* !SVR4 */
296 }
297 return 0;
298}
299
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000300#ifdef ALPHA
301int
302sys_osf_settimeofday(tcp)
303struct tcb *tcp;
304{
305 if (entering(tcp)) {
Roland McGrath6afc5652007-07-24 01:57:11 +0000306 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000307#ifndef SVR4
308 tprintf(", ");
Roland McGrath6afc5652007-07-24 01:57:11 +0000309 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000310#endif /* !SVR4 */
311 }
312 return 0;
313}
314#endif
315
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000316int
317sys_adjtime(tcp)
318struct tcb *tcp;
319{
320 if (entering(tcp)) {
321 printtv(tcp, tcp->u_arg[0]);
322 tprintf(", ");
323 } else {
324 if (syserror(tcp))
325 tprintf("%#lx", tcp->u_arg[1]);
326 else
327 printtv(tcp, tcp->u_arg[1]);
328 }
329 return 0;
330}
331
Dmitry V. Levin2e55ff42008-09-03 01:02:46 +0000332int
333sys_nanosleep(struct tcb *tcp)
334{
335 if (entering(tcp)) {
336 print_timespec(tcp, tcp->u_arg[0]);
337 tprintf(", ");
338 } else {
339 if (!tcp->u_arg[1] || is_restart_error(tcp))
340 print_timespec(tcp, tcp->u_arg[1]);
341 else
342 tprintf("%#lx", tcp->u_arg[1]);
343 }
344 return 0;
345}
346
Roland McGrathd9f816f2004-09-04 03:39:20 +0000347static const struct xlat which[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000348 { ITIMER_REAL, "ITIMER_REAL" },
349 { ITIMER_VIRTUAL,"ITIMER_VIRTUAL"},
350 { ITIMER_PROF, "ITIMER_PROF" },
351 { 0, NULL },
352};
353
354static void
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000355printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000356{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000357 if (addr == 0)
358 tprintf("NULL");
359 else if (!verbose(tcp))
360 tprintf("%#lx", addr);
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000361 else
362 {
363 int rc;
364
365 if (bitness == BITNESS_32
366#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
367 || personality_wordsize[current_personality] == 4
368#endif
369 )
370 {
371 struct
372 {
373 struct timeval32 it_interval, it_value;
374 } itv;
375
Roland McGrathe4662342007-08-02 01:25:34 +0000376 if ((rc = umove(tcp, addr, &itv)) >= 0) {
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000377 tprintf("{it_interval=");
378 tprint_timeval32(tcp, &itv.it_interval);
379 tprintf(", it_value=");
380 tprint_timeval32(tcp, &itv.it_value);
381 tprintf("}");
Roland McGrathe4662342007-08-02 01:25:34 +0000382 }
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000383 } else
384 {
385 struct itimerval itv;
386
Roland McGrathe4662342007-08-02 01:25:34 +0000387 if ((rc = umove(tcp, addr, &itv)) >= 0) {
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000388 tprintf("{it_interval=");
389 tprint_timeval(tcp, &itv.it_interval);
390 tprintf(", it_value=");
391 tprint_timeval(tcp, &itv.it_value);
392 tprintf("}");
Roland McGrathe4662342007-08-02 01:25:34 +0000393 }
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000394 }
395
396 if (rc < 0)
397 tprintf("{...}");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000398 }
399}
400
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000401#define printitv(tcp, addr) \
402 printitv_bitness((tcp), (addr), BITNESS_CURRENT)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000403
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000404int
405sys_getitimer(tcp)
406struct tcb *tcp;
407{
408 if (entering(tcp)) {
409 printxval(which, tcp->u_arg[0], "ITIMER_???");
410 tprintf(", ");
411 } else {
412 if (syserror(tcp))
413 tprintf("%#lx", tcp->u_arg[1]);
414 else
415 printitv(tcp, tcp->u_arg[1]);
416 }
417 return 0;
418}
419
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000420
421#ifdef ALPHA
422int
423sys_osf_getitimer(tcp)
424struct tcb *tcp;
425{
426 if (entering(tcp)) {
427 printxval(which, tcp->u_arg[0], "ITIMER_???");
428 tprintf(", ");
429 } else {
430 if (syserror(tcp))
431 tprintf("%#lx", tcp->u_arg[1]);
432 else
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000433 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000434 }
435 return 0;
436}
437#endif
438
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000439int
440sys_setitimer(tcp)
441struct tcb *tcp;
442{
443 if (entering(tcp)) {
444 printxval(which, tcp->u_arg[0], "ITIMER_???");
445 tprintf(", ");
446 printitv(tcp, tcp->u_arg[1]);
447 tprintf(", ");
448 } else {
449 if (syserror(tcp))
450 tprintf("%#lx", tcp->u_arg[2]);
451 else
452 printitv(tcp, tcp->u_arg[2]);
453 }
454 return 0;
455}
456
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000457#ifdef ALPHA
458int
459sys_osf_setitimer(tcp)
460struct tcb *tcp;
461{
462 if (entering(tcp)) {
463 printxval(which, tcp->u_arg[0], "ITIMER_???");
464 tprintf(", ");
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000465 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000466 tprintf(", ");
467 } else {
468 if (syserror(tcp))
469 tprintf("%#lx", tcp->u_arg[2]);
470 else
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000471 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000472 }
473 return 0;
474}
475#endif
476
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477#ifdef LINUX
478
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000479static const struct xlat adjtimex_modes[] = {
480 { 0, "0" },
481#ifdef ADJ_OFFSET
482 { ADJ_OFFSET, "ADJ_OFFSET" },
483#endif
484#ifdef ADJ_FREQUENCY
485 { ADJ_FREQUENCY, "ADJ_FREQUENCY" },
486#endif
487#ifdef ADJ_MAXERROR
488 { ADJ_MAXERROR, "ADJ_MAXERROR" },
489#endif
490#ifdef ADJ_ESTERROR
491 { ADJ_ESTERROR, "ADJ_ESTERROR" },
492#endif
493#ifdef ADJ_STATUS
494 { ADJ_STATUS, "ADJ_STATUS" },
495#endif
496#ifdef ADJ_TIMECONST
497 { ADJ_TIMECONST, "ADJ_TIMECONST" },
498#endif
499#ifdef ADJ_TICK
500 { ADJ_TICK, "ADJ_TICK" },
501#endif
502#ifdef ADJ_OFFSET_SINGLESHOT
503 { ADJ_OFFSET_SINGLESHOT, "ADJ_OFFSET_SINGLESHOT" },
504#endif
505 { 0, NULL }
506};
507
508static const struct xlat adjtimex_status[] = {
509#ifdef STA_PLL
510 { STA_PLL, "STA_PLL" },
511#endif
512#ifdef STA_PPSFREQ
513 { STA_PPSFREQ, "STA_PPSFREQ" },
514#endif
515#ifdef STA_PPSTIME
516 { STA_PPSTIME, "STA_PPSTIME" },
517#endif
518#ifdef STA_FLL
519 { STA_FLL, "STA_FLL" },
520#endif
521#ifdef STA_INS
522 { STA_INS, "STA_INS" },
523#endif
524#ifdef STA_DEL
525 { STA_DEL, "STA_DEL" },
526#endif
527#ifdef STA_UNSYNC
528 { STA_UNSYNC, "STA_UNSYNC" },
529#endif
530#ifdef STA_FREQHOLD
531 { STA_FREQHOLD, "STA_FREQHOLD" },
532#endif
533#ifdef STA_PPSSIGNAL
534 { STA_PPSSIGNAL, "STA_PPSSIGNAL" },
535#endif
536#ifdef STA_PPSJITTER
537 { STA_PPSJITTER, "STA_PPSJITTER" },
538#endif
539#ifdef STA_PPSWANDER
540 { STA_PPSWANDER, "STA_PPSWANDER" },
541#endif
542#ifdef STA_PPSERROR
543 { STA_PPSERROR, "STA_PPSERROR" },
544#endif
545#ifdef STA_CLOCKERR
546 { STA_CLOCKERR, "STA_CLOCKERR" },
547#endif
548 { 0, NULL }
549};
550
551static const struct xlat adjtimex_state[] = {
552#ifdef TIME_OK
553 { TIME_OK, "TIME_OK" },
554#endif
555#ifdef TIME_INS
556 { TIME_INS, "TIME_INS" },
557#endif
558#ifdef TIME_DEL
559 { TIME_DEL, "TIME_DEL" },
560#endif
561#ifdef TIME_OOP
562 { TIME_OOP, "TIME_OOP" },
563#endif
564#ifdef TIME_WAIT
565 { TIME_WAIT, "TIME_WAIT" },
566#endif
567#ifdef TIME_ERROR
568 { TIME_ERROR, "TIME_ERROR" },
569#endif
570 { 0, NULL }
571};
572
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000573#if SUPPORTED_PERSONALITIES > 1
574static int
575tprint_timex32(struct tcb *tcp, long addr)
576{
577 struct
578 {
579 unsigned int modes;
580 int offset;
581 int freq;
582 int maxerror;
583 int esterror;
584 int status;
585 int constant;
586 int precision;
587 int tolerance;
588 struct timeval32 time;
589 int tick;
590 int ppsfreq;
591 int jitter;
592 int shift;
593 int stabil;
594 int jitcnt;
595 int calcnt;
596 int errcnt;
597 int stbcnt;
598 } tx;
599
600 if (umove(tcp, addr, &tx) < 0)
601 return -1;
602
603 tprintf("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000604 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000605 tprintf(", offset=%d, freq=%d, maxerror=%d, ",
606 tx.offset, tx.freq, tx.maxerror);
607 tprintf("esterror=%u, status=", tx.esterror);
608 printflags(adjtimex_status, tx.status, "STA_???");
609 tprintf(", constant=%d, precision=%u, ",
610 tx.constant, tx.precision);
611 tprintf("tolerance=%d, time=", tx.tolerance);
612 tprint_timeval32(tcp, &tx.time);
613 tprintf(", tick=%d, ppsfreq=%d, jitter=%d",
614 tx.tick, tx.ppsfreq, tx.jitter);
615 tprintf(", shift=%d, stabil=%d, jitcnt=%d",
616 tx.shift, tx.stabil, tx.jitcnt);
617 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d",
618 tx.calcnt, tx.errcnt, tx.stbcnt);
619 tprintf("}");
620 return 0;
621}
622#endif /* SUPPORTED_PERSONALITIES > 1 */
623
624static int
625tprint_timex(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000626{
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000627 struct timex tx;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000628
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000629#if SUPPORTED_PERSONALITIES > 1
630 if (personality_wordsize[current_personality] == 4)
631 return tprint_timex32(tcp, addr);
632#endif
633 if (umove(tcp, addr, &tx) < 0)
634 return -1;
635
636#if LINUX_VERSION_CODE < 66332
637 tprintf("{mode=%d, offset=%ld, frequency=%ld, ",
638 tx.mode, tx.offset, tx.frequency);
639 tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
640 tx.maxerror, tx.esterror, tx.status);
641 tprintf("time_constant=%ld, precision=%lu, ",
642 tx.time_constant, tx.precision);
643 tprintf("tolerance=%ld, time=", tx.tolerance);
644 tprint_timeval(tcp, &tx.time);
645#else
646 tprintf("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000647 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000648 tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ",
649 tx.offset, tx.freq, tx.maxerror);
650 tprintf("esterror=%lu, status=", tx.esterror);
651 printflags(adjtimex_status, tx.status, "STA_???");
652 tprintf(", constant=%ld, precision=%lu, ",
653 tx.constant, tx.precision);
654 tprintf("tolerance=%ld, time=", tx.tolerance);
655 tprint_timeval(tcp, &tx.time);
656 tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld",
657 tx.tick, tx.ppsfreq, tx.jitter);
658 tprintf(", shift=%d, stabil=%ld, jitcnt=%ld",
659 tx.shift, tx.stabil, tx.jitcnt);
660 tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld",
661 tx.calcnt, tx.errcnt, tx.stbcnt);
662#endif
663 tprintf("}");
664 return 0;
665}
666
667int
668sys_adjtimex(struct tcb *tcp)
669{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000670 if (exiting(tcp)) {
671 if (tcp->u_arg[0] == 0)
672 tprintf("NULL");
673 else if (syserror(tcp) || !verbose(tcp))
674 tprintf("%#lx", tcp->u_arg[0]);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000675 else if (tprint_timex(tcp, tcp->u_arg[0]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000676 tprintf("{...}");
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000677 if (syserror(tcp))
678 return 0;
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000679 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
680 if (tcp->auxstr)
681 return RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000682 }
683 return 0;
684}
Roland McGrath1e356792003-03-30 23:52:28 +0000685
Roland McGrathd9f816f2004-09-04 03:39:20 +0000686static const struct xlat clockflags[] = {
Roland McGrath1e356792003-03-30 23:52:28 +0000687 { TIMER_ABSTIME, "TIMER_ABSTIME" },
688 { 0, NULL }
689};
690
Roland McGrathd9f816f2004-09-04 03:39:20 +0000691static const struct xlat clocknames[] = {
Roland McGrath55a00f82004-08-31 08:26:39 +0000692#ifdef CLOCK_REALTIME
Roland McGrath54a4edd2004-08-31 06:52:45 +0000693 { CLOCK_REALTIME, "CLOCK_REALTIME" },
Roland McGrath55a00f82004-08-31 08:26:39 +0000694#endif
695#ifdef CLOCK_MONOTONIC
Roland McGrath54a4edd2004-08-31 06:52:45 +0000696 { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" },
Roland McGrath55a00f82004-08-31 08:26:39 +0000697#endif
Roland McGrath54a4edd2004-08-31 06:52:45 +0000698 { 0, NULL }
699};
700
Roland McGrath1e356792003-03-30 23:52:28 +0000701int
702sys_clock_settime(tcp)
703struct tcb *tcp;
704{
705 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000706 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
707 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000708 printtv(tcp, tcp->u_arg[1]);
709 }
710 return 0;
711}
712
713int
714sys_clock_gettime(tcp)
715struct tcb *tcp;
716{
717 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000718 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
719 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000720 } else {
721 if (syserror(tcp))
722 tprintf("%#lx", tcp->u_arg[1]);
723 else
724 printtv(tcp, tcp->u_arg[1]);
725 }
726 return 0;
727}
728
729int
730sys_clock_nanosleep(tcp)
731struct tcb *tcp;
732{
733 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000734 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
735 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000736 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Roland McGrath1e356792003-03-30 23:52:28 +0000737 tprintf(", ");
738 printtv(tcp, tcp->u_arg[2]);
739 tprintf(", ");
740 } else {
741 if (syserror(tcp))
742 tprintf("%#lx", tcp->u_arg[3]);
743 else
744 printtv(tcp, tcp->u_arg[3]);
745 }
746 return 0;
747}
748
749#ifndef SIGEV_THREAD_ID
750# define SIGEV_THREAD_ID 4
751#endif
Roland McGrathd9f816f2004-09-04 03:39:20 +0000752static const struct xlat sigev_value[] = {
Roland McGrath1e356792003-03-30 23:52:28 +0000753 { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" },
754 { SIGEV_NONE+1, "SIGEV_NONE" },
755 { SIGEV_THREAD+1, "SIGEV_THREAD" },
756 { SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" },
757 { 0, NULL }
758};
759
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000760#if SUPPORTED_PERSONALITIES > 1
761static void
762printsigevent32(struct tcb *tcp, long arg)
763{
764 struct
765 {
766 int sigev_value;
767 int sigev_signo;
768 int sigev_notify;
769
770 union
771 {
772 int tid;
773 struct
774 {
775 int function, attribute;
776 } thread;
777 } un;
778 } sev;
779
780 if (umove(tcp, arg, &sev) < 0)
781 tprintf("{...}");
782 else
783 {
784 tprintf("{%#x, ", sev.sigev_value);
785 if (sev.sigev_notify == SIGEV_SIGNAL)
786 tprintf("%s, ", signame(sev.sigev_signo));
787 else
788 tprintf("%u, ", sev.sigev_signo);
789 printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???");
790 tprintf(", ");
791 if (sev.sigev_notify == SIGEV_THREAD_ID)
792 tprintf("{%d}", sev.un.tid);
793 else if (sev.sigev_notify == SIGEV_THREAD)
794 tprintf("{%#x, %#x}",
795 sev.un.thread.function,
796 sev.un.thread.attribute);
797 else
798 tprintf("{...}");
799 tprintf("}");
800 }
801}
802#endif
803
Roland McGrath1e356792003-03-30 23:52:28 +0000804void
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000805printsigevent(struct tcb *tcp, long arg)
Roland McGrath1e356792003-03-30 23:52:28 +0000806{
807 struct sigevent sev;
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000808
809#if SUPPORTED_PERSONALITIES > 1
810 if (personality_wordsize[current_personality] == 4)
811 {
812 printsigevent32(tcp, arg);
813 return;
814 }
815#endif
Roland McGrath1e356792003-03-30 23:52:28 +0000816 if (umove (tcp, arg, &sev) < 0)
817 tprintf("{...}");
818 else {
Roland McGrath675d4a62004-09-11 08:12:45 +0000819 tprintf("{%p, ", sev.sigev_value.sival_ptr);
820 if (sev.sigev_notify == SIGEV_SIGNAL)
821 tprintf("%s, ", signame(sev.sigev_signo));
822 else
823 tprintf("%u, ", sev.sigev_signo);
Roland McGrath1e356792003-03-30 23:52:28 +0000824 printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???");
825 tprintf(", ");
826 if (sev.sigev_notify == SIGEV_THREAD_ID)
827 /* _pad[0] is the _tid field which might not be
828 present in the userlevel definition of the
829 struct. */
830 tprintf("{%d}", sev._sigev_un._pad[0]);
Roland McGrathd4c85eb2004-04-16 21:48:44 +0000831 else if (sev.sigev_notify == SIGEV_THREAD)
832 tprintf("{%p, %p}", sev.sigev_notify_function,
833 sev.sigev_notify_attributes);
Roland McGrath1e356792003-03-30 23:52:28 +0000834 else
835 tprintf("{...}");
836 tprintf("}");
837 }
838}
839
840int
841sys_timer_create(tcp)
842struct tcb *tcp;
843{
844 if (entering(tcp)) {
Roland McGrath675d4a62004-09-11 08:12:45 +0000845 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
846 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000847 printsigevent(tcp, tcp->u_arg[1]);
848 tprintf(", ");
849 } else {
Dmitry V. Levinac518d12006-12-13 17:03:02 +0000850 void *p;
851
852 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrath1e356792003-03-30 23:52:28 +0000853 tprintf("%#lx", tcp->u_arg[2]);
Dmitry V. Levinac518d12006-12-13 17:03:02 +0000854 else
Roland McGrath1e356792003-03-30 23:52:28 +0000855 tprintf("{%p}", p);
Roland McGrath1e356792003-03-30 23:52:28 +0000856 }
857 return 0;
858}
859
860int
861sys_timer_settime(tcp)
862struct tcb *tcp;
863{
864 if (entering(tcp)) {
865 tprintf("%#lx, ", tcp->u_arg[0]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000866 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Roland McGrath1e356792003-03-30 23:52:28 +0000867 tprintf(", ");
868 printitv(tcp, tcp->u_arg[2]);
869 tprintf(", ");
870 } else {
871 if (syserror(tcp))
872 tprintf("%#lx", tcp->u_arg[3]);
873 else
874 printitv(tcp, tcp->u_arg[3]);
875 }
876 return 0;
877}
878
879int
880sys_timer_gettime(tcp)
881struct tcb *tcp;
882{
883 if (entering(tcp)) {
884 tprintf("%#lx, ", tcp->u_arg[0]);
885 } else {
886 if (syserror(tcp))
887 tprintf("%#lx", tcp->u_arg[1]);
888 else
889 printitv(tcp, tcp->u_arg[1]);
890 }
891 return 0;
892}
Roland McGrathd83c50b2004-10-06 22:27:43 +0000893
894static void
895print_rtc(tcp, rt)
896struct tcb *tcp;
897const struct rtc_time *rt;
898{
899 tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, "
900 "tm_mday=%d, tm_mon=%d, tm_year=%d, ",
901 rt->tm_sec, rt->tm_min, rt->tm_hour,
902 rt->tm_mday, rt->tm_mon, rt->tm_year);
903 if (!abbrev(tcp))
904 tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
905 rt->tm_wday, rt->tm_yday, rt->tm_isdst);
906 else
907 tprintf("...}");
908}
909
910int
911rtc_ioctl(tcp, code, arg)
912struct tcb *tcp;
913long code;
914long arg;
915{
916 switch (code) {
917 case RTC_ALM_SET:
918 case RTC_SET_TIME:
919 if (entering(tcp)) {
920 struct rtc_time rt;
921 if (umove(tcp, arg, &rt) < 0)
922 tprintf(", %#lx", arg);
923 else {
924 tprintf(", ");
925 print_rtc(tcp, &rt);
926 }
927 }
928 break;
929 case RTC_ALM_READ:
930 case RTC_RD_TIME:
931 if (exiting(tcp)) {
932 struct rtc_time rt;
933 if (syserror(tcp) || umove(tcp, arg, &rt) < 0)
934 tprintf(", %#lx", arg);
935 else {
936 tprintf(", ");
937 print_rtc(tcp, &rt);
938 }
939 }
940 break;
941 case RTC_IRQP_SET:
942 case RTC_EPOCH_SET:
943 if (entering(tcp))
944 tprintf(", %lu", arg);
945 break;
946 case RTC_IRQP_READ:
947 case RTC_EPOCH_READ:
948 if (exiting(tcp))
949 tprintf(", %lu", arg);
950 break;
951 case RTC_WKALM_SET:
952 if (entering(tcp)) {
953 struct rtc_wkalrm wk;
954 if (umove(tcp, arg, &wk) < 0)
955 tprintf(", %#lx", arg);
956 else {
957 tprintf(", {enabled=%d, pending=%d, ",
958 wk.enabled, wk.pending);
959 print_rtc(tcp, &wk.time);
960 tprintf("}");
961 }
962 }
963 break;
964 case RTC_WKALM_RD:
965 if (exiting(tcp)) {
966 struct rtc_wkalrm wk;
967 if (syserror(tcp) || umove(tcp, arg, &wk) < 0)
968 tprintf(", %#lx", arg);
969 else {
970 tprintf(", {enabled=%d, pending=%d, ",
971 wk.enabled, wk.pending);
972 print_rtc(tcp, &wk.time);
973 tprintf("}");
974 }
975 }
976 break;
977 default:
978 if (entering(tcp))
979 tprintf(", %#lx", arg);
980 break;
981 }
982 return 1;
983}
Roland McGrathe4662342007-08-02 01:25:34 +0000984
985#ifndef TFD_TIMER_ABSTIME
986#define TFD_TIMER_ABSTIME (1 << 0)
987#endif
988
989static const struct xlat timerfdflags[] = {
990 { TFD_TIMER_ABSTIME, "TFD_TIMER_ABSTIME" },
991 { 0, NULL }
992};
993
994int
995sys_timerfd(tcp)
996struct tcb *tcp;
997{
998 if (entering(tcp)) {
999 /* It does not matter that the kernel uses itimerspec. */
1000 tprintf("%ld, ", tcp->u_arg[0]);
1001 printxval(clocknames, tcp->u_arg[1], "CLOCK_???");
1002 tprintf(", ");
1003 printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
1004 tprintf(", ");
1005 printitv(tcp, tcp->u_arg[3]);
1006 }
1007 return 0;
1008}
Roland McGrathde328e62008-05-20 04:56:13 +00001009
1010int
1011sys_timerfd_create(struct tcb *tcp)
1012{
1013 if (entering(tcp)) {
1014 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
1015 tprintf(", ");
1016 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
1017 }
1018 return 0;
1019}
1020
1021int
1022sys_timerfd_settime(struct tcb *tcp)
1023{
1024 if (entering(tcp)) {
1025 tprintf("%ld, ", tcp->u_arg[0]);
1026 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
1027 tprintf(", ");
1028 printitv(tcp, tcp->u_arg[2]);
1029 tprintf(", ");
1030 printitv(tcp, tcp->u_arg[3]);
1031 }
1032 return 0;
1033}
1034
1035int
1036sys_timerfd_gettime(struct tcb *tcp)
1037{
1038 if (entering(tcp)) {
1039 tprintf("%ld, ", tcp->u_arg[0]);
1040 tprintf(", ");
1041 printitv(tcp, tcp->u_arg[1]);
1042 }
1043 return 0;
1044}
1045
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001046#endif /* LINUX */