blob: 3d2f6c99c7b684889e596d3af72e8e809896738d [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>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000039#endif /* LINUX */
40
Dmitry V. Levina7945a32006-12-13 17:10:11 +000041struct timeval32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000042{
Dmitry V. Levina7945a32006-12-13 17:10:11 +000043 u_int32_t tv_sec, tv_usec;
44};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000045
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000046static void
47tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv)
48{
49 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec);
50}
51
52static void
53tprint_timeval(struct tcb *tcp, const struct timeval *tv)
54{
55 tprintf("{%lu, %lu}",
56 (unsigned long) tv->tv_sec, (unsigned long) tv->tv_usec);
57}
58
Dmitry V. Levina7945a32006-12-13 17:10:11 +000059void
60printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
61{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000062 if (addr == 0)
63 tprintf("NULL");
64 else if (!verbose(tcp))
65 tprintf("%#lx", addr);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000066 else
Dmitry V. Levina7945a32006-12-13 17:10:11 +000067 {
68 int rc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000069
Dmitry V. Levina7945a32006-12-13 17:10:11 +000070 if (bitness == BITNESS_32
71#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
72 || personality_wordsize[current_personality] == 4
73#endif
74 )
75 {
76 struct timeval32 tv;
77
78 if ((rc = umove(tcp, addr, &tv)) >= 0)
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000079 tprint_timeval32(tcp, &tv);
Dmitry V. Levina7945a32006-12-13 17:10:11 +000080 } else
81 {
82 struct timeval tv;
83
84 if ((rc = umove(tcp, addr, &tv)) >= 0)
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +000085 tprint_timeval(tcp, &tv);
Dmitry V. Levina7945a32006-12-13 17:10:11 +000086 }
87
88 if (rc < 0)
89 tprintf("{...}");
90 }
91}
Wichert Akkerman221f54f1999-11-18 17:26:45 +000092
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000093void
Dmitry V. Levina7945a32006-12-13 17:10:11 +000094sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000095{
Dmitry V. Levina7945a32006-12-13 17:10:11 +000096 if (addr == 0)
97 strcpy(buf, "NULL");
98 else if (!verbose(tcp))
99 sprintf(buf, "%#lx", addr);
100 else
101 {
102 int rc;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000103
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000104 if (bitness == BITNESS_32
105#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
106 || personality_wordsize[current_personality] == 4
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000107#endif
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000108 )
109 {
110 struct timeval32 tv;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000111
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000112 if ((rc = umove(tcp, addr, &tv)) >= 0)
113 sprintf(buf, "{%u, %u}",
114 tv.tv_sec, tv.tv_usec);
115 } else
116 {
117 struct timeval tv;
118
119 if ((rc = umove(tcp, addr, &tv)) >= 0)
120 sprintf(buf, "{%lu, %lu}",
121 (unsigned long) tv.tv_sec,
122 (unsigned long) tv.tv_usec);
123 }
124
125 if (rc < 0)
126 strcpy(buf, "{...}");
127 }
128}
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000129
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000130int
131sys_time(tcp)
132struct tcb *tcp;
133{
134 if (exiting(tcp)) {
135#ifndef SVR4
136 printnum(tcp, tcp->u_arg[0], "%ld");
137#endif /* SVR4 */
138 }
139 return 0;
140}
141
142int
143sys_stime(tcp)
144struct tcb *tcp;
145{
146 if (exiting(tcp)) {
147 printnum(tcp, tcp->u_arg[0], "%ld");
148 }
149 return 0;
150}
151
152int
153sys_gettimeofday(tcp)
154struct tcb *tcp;
155{
156 if (exiting(tcp)) {
157 if (syserror(tcp)) {
158 tprintf("%#lx, %#lx",
159 tcp->u_arg[0], tcp->u_arg[1]);
160 return 0;
161 }
162 printtv(tcp, tcp->u_arg[0]);
163#ifndef SVR4
164 tprintf(", ");
165 printtv(tcp, tcp->u_arg[1]);
166#endif /* !SVR4 */
167 }
168 return 0;
169}
170
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000171
172#ifdef ALPHA
173int
174sys_osf_gettimeofday(tcp)
175struct tcb *tcp;
176{
177 if (exiting(tcp)) {
178 if (syserror(tcp)) {
179 tprintf("%#lx, %#lx",
180 tcp->u_arg[0], tcp->u_arg[1]);
181 return 0;
182 }
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000183 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000184#ifndef SVR4
185 tprintf(", ");
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000186 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000187#endif /* !SVR4 */
188 }
189 return 0;
190}
191#endif
192
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000193int
194sys_settimeofday(tcp)
195struct tcb *tcp;
196{
197 if (entering(tcp)) {
198 printtv(tcp, tcp->u_arg[0]);
199#ifndef SVR4
200 tprintf(", ");
201 printtv(tcp, tcp->u_arg[1]);
202#endif /* !SVR4 */
203 }
204 return 0;
205}
206
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000207#ifdef ALPHA
208int
209sys_osf_settimeofday(tcp)
210struct tcb *tcp;
211{
212 if (entering(tcp)) {
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000213 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000214#ifndef SVR4
215 tprintf(", ");
Dmitry V. Levina7945a32006-12-13 17:10:11 +0000216 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000217#endif /* !SVR4 */
218 }
219 return 0;
220}
221#endif
222
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223int
224sys_adjtime(tcp)
225struct tcb *tcp;
226{
227 if (entering(tcp)) {
228 printtv(tcp, tcp->u_arg[0]);
229 tprintf(", ");
230 } else {
231 if (syserror(tcp))
232 tprintf("%#lx", tcp->u_arg[1]);
233 else
234 printtv(tcp, tcp->u_arg[1]);
235 }
236 return 0;
237}
238
Roland McGrathd9f816f2004-09-04 03:39:20 +0000239static const struct xlat which[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000240 { ITIMER_REAL, "ITIMER_REAL" },
241 { ITIMER_VIRTUAL,"ITIMER_VIRTUAL"},
242 { ITIMER_PROF, "ITIMER_PROF" },
243 { 0, NULL },
244};
245
246static void
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000247printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000248{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000249 if (addr == 0)
250 tprintf("NULL");
251 else if (!verbose(tcp))
252 tprintf("%#lx", addr);
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000253 else
254 {
255 int rc;
256
257 if (bitness == BITNESS_32
258#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
259 || personality_wordsize[current_personality] == 4
260#endif
261 )
262 {
263 struct
264 {
265 struct timeval32 it_interval, it_value;
266 } itv;
267
268 if ((rc = umove(tcp, addr, &itv)) >= 0)
269 tprintf("{it_interval=");
270 tprint_timeval32(tcp, &itv.it_interval);
271 tprintf(", it_value=");
272 tprint_timeval32(tcp, &itv.it_value);
273 tprintf("}");
274 } else
275 {
276 struct itimerval itv;
277
278 if ((rc = umove(tcp, addr, &itv)) >= 0)
279 tprintf("{it_interval=");
280 tprint_timeval(tcp, &itv.it_interval);
281 tprintf(", it_value=");
282 tprint_timeval(tcp, &itv.it_value);
283 tprintf("}");
284 }
285
286 if (rc < 0)
287 tprintf("{...}");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000288 }
289}
290
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000291#define printitv(tcp, addr) \
292 printitv_bitness((tcp), (addr), BITNESS_CURRENT)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000293
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000294int
295sys_getitimer(tcp)
296struct tcb *tcp;
297{
298 if (entering(tcp)) {
299 printxval(which, tcp->u_arg[0], "ITIMER_???");
300 tprintf(", ");
301 } else {
302 if (syserror(tcp))
303 tprintf("%#lx", tcp->u_arg[1]);
304 else
305 printitv(tcp, tcp->u_arg[1]);
306 }
307 return 0;
308}
309
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000310
311#ifdef ALPHA
312int
313sys_osf_getitimer(tcp)
314struct tcb *tcp;
315{
316 if (entering(tcp)) {
317 printxval(which, tcp->u_arg[0], "ITIMER_???");
318 tprintf(", ");
319 } else {
320 if (syserror(tcp))
321 tprintf("%#lx", tcp->u_arg[1]);
322 else
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000323 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000324 }
325 return 0;
326}
327#endif
328
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000329int
330sys_setitimer(tcp)
331struct tcb *tcp;
332{
333 if (entering(tcp)) {
334 printxval(which, tcp->u_arg[0], "ITIMER_???");
335 tprintf(", ");
336 printitv(tcp, tcp->u_arg[1]);
337 tprintf(", ");
338 } else {
339 if (syserror(tcp))
340 tprintf("%#lx", tcp->u_arg[2]);
341 else
342 printitv(tcp, tcp->u_arg[2]);
343 }
344 return 0;
345}
346
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000347#ifdef ALPHA
348int
349sys_osf_setitimer(tcp)
350struct tcb *tcp;
351{
352 if (entering(tcp)) {
353 printxval(which, tcp->u_arg[0], "ITIMER_???");
354 tprintf(", ");
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000355 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000356 tprintf(", ");
357 } else {
358 if (syserror(tcp))
359 tprintf("%#lx", tcp->u_arg[2]);
360 else
Dmitry V. Levin1cad25d2006-12-13 17:14:36 +0000361 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000362 }
363 return 0;
364}
365#endif
366
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000367#ifdef LINUX
368
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000369static const struct xlat adjtimex_modes[] = {
370 { 0, "0" },
371#ifdef ADJ_OFFSET
372 { ADJ_OFFSET, "ADJ_OFFSET" },
373#endif
374#ifdef ADJ_FREQUENCY
375 { ADJ_FREQUENCY, "ADJ_FREQUENCY" },
376#endif
377#ifdef ADJ_MAXERROR
378 { ADJ_MAXERROR, "ADJ_MAXERROR" },
379#endif
380#ifdef ADJ_ESTERROR
381 { ADJ_ESTERROR, "ADJ_ESTERROR" },
382#endif
383#ifdef ADJ_STATUS
384 { ADJ_STATUS, "ADJ_STATUS" },
385#endif
386#ifdef ADJ_TIMECONST
387 { ADJ_TIMECONST, "ADJ_TIMECONST" },
388#endif
389#ifdef ADJ_TICK
390 { ADJ_TICK, "ADJ_TICK" },
391#endif
392#ifdef ADJ_OFFSET_SINGLESHOT
393 { ADJ_OFFSET_SINGLESHOT, "ADJ_OFFSET_SINGLESHOT" },
394#endif
395 { 0, NULL }
396};
397
398static const struct xlat adjtimex_status[] = {
399#ifdef STA_PLL
400 { STA_PLL, "STA_PLL" },
401#endif
402#ifdef STA_PPSFREQ
403 { STA_PPSFREQ, "STA_PPSFREQ" },
404#endif
405#ifdef STA_PPSTIME
406 { STA_PPSTIME, "STA_PPSTIME" },
407#endif
408#ifdef STA_FLL
409 { STA_FLL, "STA_FLL" },
410#endif
411#ifdef STA_INS
412 { STA_INS, "STA_INS" },
413#endif
414#ifdef STA_DEL
415 { STA_DEL, "STA_DEL" },
416#endif
417#ifdef STA_UNSYNC
418 { STA_UNSYNC, "STA_UNSYNC" },
419#endif
420#ifdef STA_FREQHOLD
421 { STA_FREQHOLD, "STA_FREQHOLD" },
422#endif
423#ifdef STA_PPSSIGNAL
424 { STA_PPSSIGNAL, "STA_PPSSIGNAL" },
425#endif
426#ifdef STA_PPSJITTER
427 { STA_PPSJITTER, "STA_PPSJITTER" },
428#endif
429#ifdef STA_PPSWANDER
430 { STA_PPSWANDER, "STA_PPSWANDER" },
431#endif
432#ifdef STA_PPSERROR
433 { STA_PPSERROR, "STA_PPSERROR" },
434#endif
435#ifdef STA_CLOCKERR
436 { STA_CLOCKERR, "STA_CLOCKERR" },
437#endif
438 { 0, NULL }
439};
440
441static const struct xlat adjtimex_state[] = {
442#ifdef TIME_OK
443 { TIME_OK, "TIME_OK" },
444#endif
445#ifdef TIME_INS
446 { TIME_INS, "TIME_INS" },
447#endif
448#ifdef TIME_DEL
449 { TIME_DEL, "TIME_DEL" },
450#endif
451#ifdef TIME_OOP
452 { TIME_OOP, "TIME_OOP" },
453#endif
454#ifdef TIME_WAIT
455 { TIME_WAIT, "TIME_WAIT" },
456#endif
457#ifdef TIME_ERROR
458 { TIME_ERROR, "TIME_ERROR" },
459#endif
460 { 0, NULL }
461};
462
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000463#if SUPPORTED_PERSONALITIES > 1
464static int
465tprint_timex32(struct tcb *tcp, long addr)
466{
467 struct
468 {
469 unsigned int modes;
470 int offset;
471 int freq;
472 int maxerror;
473 int esterror;
474 int status;
475 int constant;
476 int precision;
477 int tolerance;
478 struct timeval32 time;
479 int tick;
480 int ppsfreq;
481 int jitter;
482 int shift;
483 int stabil;
484 int jitcnt;
485 int calcnt;
486 int errcnt;
487 int stbcnt;
488 } tx;
489
490 if (umove(tcp, addr, &tx) < 0)
491 return -1;
492
493 tprintf("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000494 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000495 tprintf(", offset=%d, freq=%d, maxerror=%d, ",
496 tx.offset, tx.freq, tx.maxerror);
497 tprintf("esterror=%u, status=", tx.esterror);
498 printflags(adjtimex_status, tx.status, "STA_???");
499 tprintf(", constant=%d, precision=%u, ",
500 tx.constant, tx.precision);
501 tprintf("tolerance=%d, time=", tx.tolerance);
502 tprint_timeval32(tcp, &tx.time);
503 tprintf(", tick=%d, ppsfreq=%d, jitter=%d",
504 tx.tick, tx.ppsfreq, tx.jitter);
505 tprintf(", shift=%d, stabil=%d, jitcnt=%d",
506 tx.shift, tx.stabil, tx.jitcnt);
507 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d",
508 tx.calcnt, tx.errcnt, tx.stbcnt);
509 tprintf("}");
510 return 0;
511}
512#endif /* SUPPORTED_PERSONALITIES > 1 */
513
514static int
515tprint_timex(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000516{
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000517 struct timex tx;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000518
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000519#if SUPPORTED_PERSONALITIES > 1
520 if (personality_wordsize[current_personality] == 4)
521 return tprint_timex32(tcp, addr);
522#endif
523 if (umove(tcp, addr, &tx) < 0)
524 return -1;
525
526#if LINUX_VERSION_CODE < 66332
527 tprintf("{mode=%d, offset=%ld, frequency=%ld, ",
528 tx.mode, tx.offset, tx.frequency);
529 tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
530 tx.maxerror, tx.esterror, tx.status);
531 tprintf("time_constant=%ld, precision=%lu, ",
532 tx.time_constant, tx.precision);
533 tprintf("tolerance=%ld, time=", tx.tolerance);
534 tprint_timeval(tcp, &tx.time);
535#else
536 tprintf("{modes=");
Dmitry V. Levin71d70892007-01-13 11:17:38 +0000537 printflags(adjtimex_modes, tx.modes, "ADJ_???");
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000538 tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ",
539 tx.offset, tx.freq, tx.maxerror);
540 tprintf("esterror=%lu, status=", tx.esterror);
541 printflags(adjtimex_status, tx.status, "STA_???");
542 tprintf(", constant=%ld, precision=%lu, ",
543 tx.constant, tx.precision);
544 tprintf("tolerance=%ld, time=", tx.tolerance);
545 tprint_timeval(tcp, &tx.time);
546 tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld",
547 tx.tick, tx.ppsfreq, tx.jitter);
548 tprintf(", shift=%d, stabil=%ld, jitcnt=%ld",
549 tx.shift, tx.stabil, tx.jitcnt);
550 tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld",
551 tx.calcnt, tx.errcnt, tx.stbcnt);
552#endif
553 tprintf("}");
554 return 0;
555}
556
557int
558sys_adjtimex(struct tcb *tcp)
559{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000560 if (exiting(tcp)) {
561 if (tcp->u_arg[0] == 0)
562 tprintf("NULL");
563 else if (syserror(tcp) || !verbose(tcp))
564 tprintf("%#lx", tcp->u_arg[0]);
Dmitry V. Levin165b15d2006-12-13 17:43:45 +0000565 else if (tprint_timex(tcp, tcp->u_arg[0]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000566 tprintf("{...}");
Dmitry V. Levin1a684d62006-12-13 17:42:32 +0000567 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
568 if (tcp->auxstr)
569 return RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000570 }
571 return 0;
572}
Roland McGrath1e356792003-03-30 23:52:28 +0000573
Roland McGrathd9f816f2004-09-04 03:39:20 +0000574static const struct xlat clockflags[] = {
Roland McGrath1e356792003-03-30 23:52:28 +0000575 { TIMER_ABSTIME, "TIMER_ABSTIME" },
576 { 0, NULL }
577};
578
Roland McGrathd9f816f2004-09-04 03:39:20 +0000579static const struct xlat clocknames[] = {
Roland McGrath55a00f82004-08-31 08:26:39 +0000580#ifdef CLOCK_REALTIME
Roland McGrath54a4edd2004-08-31 06:52:45 +0000581 { CLOCK_REALTIME, "CLOCK_REALTIME" },
Roland McGrath55a00f82004-08-31 08:26:39 +0000582#endif
583#ifdef CLOCK_MONOTONIC
Roland McGrath54a4edd2004-08-31 06:52:45 +0000584 { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" },
Roland McGrath55a00f82004-08-31 08:26:39 +0000585#endif
Roland McGrath54a4edd2004-08-31 06:52:45 +0000586 { 0, NULL }
587};
588
Roland McGrath1e356792003-03-30 23:52:28 +0000589int
590sys_clock_settime(tcp)
591struct tcb *tcp;
592{
593 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000594 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
595 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000596 printtv(tcp, tcp->u_arg[1]);
597 }
598 return 0;
599}
600
601int
602sys_clock_gettime(tcp)
603struct tcb *tcp;
604{
605 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000606 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
607 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000608 } else {
609 if (syserror(tcp))
610 tprintf("%#lx", tcp->u_arg[1]);
611 else
612 printtv(tcp, tcp->u_arg[1]);
613 }
614 return 0;
615}
616
617int
618sys_clock_nanosleep(tcp)
619struct tcb *tcp;
620{
621 if (entering(tcp)) {
Roland McGrath54a4edd2004-08-31 06:52:45 +0000622 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
623 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000624 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Roland McGrath1e356792003-03-30 23:52:28 +0000625 tprintf(", ");
626 printtv(tcp, tcp->u_arg[2]);
627 tprintf(", ");
628 } else {
629 if (syserror(tcp))
630 tprintf("%#lx", tcp->u_arg[3]);
631 else
632 printtv(tcp, tcp->u_arg[3]);
633 }
634 return 0;
635}
636
637#ifndef SIGEV_THREAD_ID
638# define SIGEV_THREAD_ID 4
639#endif
Roland McGrathd9f816f2004-09-04 03:39:20 +0000640static const struct xlat sigev_value[] = {
Roland McGrath1e356792003-03-30 23:52:28 +0000641 { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" },
642 { SIGEV_NONE+1, "SIGEV_NONE" },
643 { SIGEV_THREAD+1, "SIGEV_THREAD" },
644 { SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" },
645 { 0, NULL }
646};
647
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000648#if SUPPORTED_PERSONALITIES > 1
649static void
650printsigevent32(struct tcb *tcp, long arg)
651{
652 struct
653 {
654 int sigev_value;
655 int sigev_signo;
656 int sigev_notify;
657
658 union
659 {
660 int tid;
661 struct
662 {
663 int function, attribute;
664 } thread;
665 } un;
666 } sev;
667
668 if (umove(tcp, arg, &sev) < 0)
669 tprintf("{...}");
670 else
671 {
672 tprintf("{%#x, ", sev.sigev_value);
673 if (sev.sigev_notify == SIGEV_SIGNAL)
674 tprintf("%s, ", signame(sev.sigev_signo));
675 else
676 tprintf("%u, ", sev.sigev_signo);
677 printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???");
678 tprintf(", ");
679 if (sev.sigev_notify == SIGEV_THREAD_ID)
680 tprintf("{%d}", sev.un.tid);
681 else if (sev.sigev_notify == SIGEV_THREAD)
682 tprintf("{%#x, %#x}",
683 sev.un.thread.function,
684 sev.un.thread.attribute);
685 else
686 tprintf("{...}");
687 tprintf("}");
688 }
689}
690#endif
691
Roland McGrath1e356792003-03-30 23:52:28 +0000692void
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000693printsigevent(struct tcb *tcp, long arg)
Roland McGrath1e356792003-03-30 23:52:28 +0000694{
695 struct sigevent sev;
Dmitry V. Levind3cb3922006-12-13 17:45:02 +0000696
697#if SUPPORTED_PERSONALITIES > 1
698 if (personality_wordsize[current_personality] == 4)
699 {
700 printsigevent32(tcp, arg);
701 return;
702 }
703#endif
Roland McGrath1e356792003-03-30 23:52:28 +0000704 if (umove (tcp, arg, &sev) < 0)
705 tprintf("{...}");
706 else {
Roland McGrath675d4a62004-09-11 08:12:45 +0000707 tprintf("{%p, ", sev.sigev_value.sival_ptr);
708 if (sev.sigev_notify == SIGEV_SIGNAL)
709 tprintf("%s, ", signame(sev.sigev_signo));
710 else
711 tprintf("%u, ", sev.sigev_signo);
Roland McGrath1e356792003-03-30 23:52:28 +0000712 printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???");
713 tprintf(", ");
714 if (sev.sigev_notify == SIGEV_THREAD_ID)
715 /* _pad[0] is the _tid field which might not be
716 present in the userlevel definition of the
717 struct. */
718 tprintf("{%d}", sev._sigev_un._pad[0]);
Roland McGrathd4c85eb2004-04-16 21:48:44 +0000719 else if (sev.sigev_notify == SIGEV_THREAD)
720 tprintf("{%p, %p}", sev.sigev_notify_function,
721 sev.sigev_notify_attributes);
Roland McGrath1e356792003-03-30 23:52:28 +0000722 else
723 tprintf("{...}");
724 tprintf("}");
725 }
726}
727
728int
729sys_timer_create(tcp)
730struct tcb *tcp;
731{
732 if (entering(tcp)) {
Roland McGrath675d4a62004-09-11 08:12:45 +0000733 printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
734 tprintf(", ");
Roland McGrath1e356792003-03-30 23:52:28 +0000735 printsigevent(tcp, tcp->u_arg[1]);
736 tprintf(", ");
737 } else {
Dmitry V. Levinac518d12006-12-13 17:03:02 +0000738 void *p;
739
740 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrath1e356792003-03-30 23:52:28 +0000741 tprintf("%#lx", tcp->u_arg[2]);
Dmitry V. Levinac518d12006-12-13 17:03:02 +0000742 else
Roland McGrath1e356792003-03-30 23:52:28 +0000743 tprintf("{%p}", p);
Roland McGrath1e356792003-03-30 23:52:28 +0000744 }
745 return 0;
746}
747
748int
749sys_timer_settime(tcp)
750struct tcb *tcp;
751{
752 if (entering(tcp)) {
753 tprintf("%#lx, ", tcp->u_arg[0]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000754 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
Roland McGrath1e356792003-03-30 23:52:28 +0000755 tprintf(", ");
756 printitv(tcp, tcp->u_arg[2]);
757 tprintf(", ");
758 } else {
759 if (syserror(tcp))
760 tprintf("%#lx", tcp->u_arg[3]);
761 else
762 printitv(tcp, tcp->u_arg[3]);
763 }
764 return 0;
765}
766
767int
768sys_timer_gettime(tcp)
769struct tcb *tcp;
770{
771 if (entering(tcp)) {
772 tprintf("%#lx, ", tcp->u_arg[0]);
773 } else {
774 if (syserror(tcp))
775 tprintf("%#lx", tcp->u_arg[1]);
776 else
777 printitv(tcp, tcp->u_arg[1]);
778 }
779 return 0;
780}
Roland McGrathd83c50b2004-10-06 22:27:43 +0000781
782static void
783print_rtc(tcp, rt)
784struct tcb *tcp;
785const struct rtc_time *rt;
786{
787 tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, "
788 "tm_mday=%d, tm_mon=%d, tm_year=%d, ",
789 rt->tm_sec, rt->tm_min, rt->tm_hour,
790 rt->tm_mday, rt->tm_mon, rt->tm_year);
791 if (!abbrev(tcp))
792 tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
793 rt->tm_wday, rt->tm_yday, rt->tm_isdst);
794 else
795 tprintf("...}");
796}
797
798int
799rtc_ioctl(tcp, code, arg)
800struct tcb *tcp;
801long code;
802long arg;
803{
804 switch (code) {
805 case RTC_ALM_SET:
806 case RTC_SET_TIME:
807 if (entering(tcp)) {
808 struct rtc_time rt;
809 if (umove(tcp, arg, &rt) < 0)
810 tprintf(", %#lx", arg);
811 else {
812 tprintf(", ");
813 print_rtc(tcp, &rt);
814 }
815 }
816 break;
817 case RTC_ALM_READ:
818 case RTC_RD_TIME:
819 if (exiting(tcp)) {
820 struct rtc_time rt;
821 if (syserror(tcp) || umove(tcp, arg, &rt) < 0)
822 tprintf(", %#lx", arg);
823 else {
824 tprintf(", ");
825 print_rtc(tcp, &rt);
826 }
827 }
828 break;
829 case RTC_IRQP_SET:
830 case RTC_EPOCH_SET:
831 if (entering(tcp))
832 tprintf(", %lu", arg);
833 break;
834 case RTC_IRQP_READ:
835 case RTC_EPOCH_READ:
836 if (exiting(tcp))
837 tprintf(", %lu", arg);
838 break;
839 case RTC_WKALM_SET:
840 if (entering(tcp)) {
841 struct rtc_wkalrm wk;
842 if (umove(tcp, arg, &wk) < 0)
843 tprintf(", %#lx", arg);
844 else {
845 tprintf(", {enabled=%d, pending=%d, ",
846 wk.enabled, wk.pending);
847 print_rtc(tcp, &wk.time);
848 tprintf("}");
849 }
850 }
851 break;
852 case RTC_WKALM_RD:
853 if (exiting(tcp)) {
854 struct rtc_wkalrm wk;
855 if (syserror(tcp) || umove(tcp, arg, &wk) < 0)
856 tprintf(", %#lx", arg);
857 else {
858 tprintf(", {enabled=%d, pending=%d, ",
859 wk.enabled, wk.pending);
860 print_rtc(tcp, &wk.time);
861 tprintf("}");
862 }
863 }
864 break;
865 default:
866 if (entering(tcp))
867 tprintf(", %#lx", arg);
868 break;
869 }
870 return 1;
871}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000872#endif /* LINUX */