• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: time.c,v 1.12 2005/06/01 19:02:38 roland Exp $
30  */
31 
32 #include "defs.h"
33 
34 #ifdef LINUX
35 #include <linux/version.h>
36 #ifdef HAVE_ANDROID_OS
37 #include <linux/timex.h>
38 #else
39 #include <sys/timex.h>
40 #endif
41 #include <linux/ioctl.h>
42 #include <linux/rtc.h>
43 #endif /* LINUX */
44 
45 void
printtv(tcp,addr)46 printtv(tcp, addr)
47 struct tcb *tcp;
48 long addr;
49 {
50 	struct timeval tv;
51 
52 	if (addr == 0)
53 		tprintf("NULL");
54 	else if (!verbose(tcp))
55 		tprintf("%#lx", addr);
56 	else if (umove(tcp, addr, &tv) < 0)
57 		tprintf("{...}");
58 	else
59 		tprintf("{%lu, %lu}", (long) tv.tv_sec, (long) tv.tv_usec);
60 }
61 
62 #ifdef ALPHA
63 struct timeval32
64 {
65     unsigned tv_sec;
66     unsigned tv_usec;
67 };
68 
69 void
printtv32(tcp,addr)70 printtv32(tcp, addr)
71 struct tcb *tcp;
72 long addr;
73 {
74     struct timeval32  tv;
75 
76     if (addr == 0)
77 	tprintf("NULL");
78     else if (!verbose(tcp))
79 	tprintf("%#lx", addr);
80     else if (umove(tcp, addr, &tv) < 0)
81 	tprintf("{...}");
82     else
83 	tprintf("{%u, %u}", tv.tv_sec, tv.tv_usec);
84 }
85 #endif
86 
87 
88 int
sys_time(tcp)89 sys_time(tcp)
90 struct tcb *tcp;
91 {
92 	if (exiting(tcp)) {
93 #ifndef SVR4
94 		printnum(tcp, tcp->u_arg[0], "%ld");
95 #endif /* SVR4 */
96 	}
97 	return 0;
98 }
99 
100 int
sys_stime(tcp)101 sys_stime(tcp)
102 struct tcb *tcp;
103 {
104 	if (exiting(tcp)) {
105 		printnum(tcp, tcp->u_arg[0], "%ld");
106 	}
107 	return 0;
108 }
109 
110 int
sys_gettimeofday(tcp)111 sys_gettimeofday(tcp)
112 struct tcb *tcp;
113 {
114 	if (exiting(tcp)) {
115 		if (syserror(tcp)) {
116 			tprintf("%#lx, %#lx",
117 				tcp->u_arg[0], tcp->u_arg[1]);
118 			return 0;
119 		}
120 		printtv(tcp, tcp->u_arg[0]);
121 #ifndef SVR4
122 		tprintf(", ");
123 		printtv(tcp, tcp->u_arg[1]);
124 #endif /* !SVR4 */
125 	}
126 	return 0;
127 }
128 
129 
130 #ifdef ALPHA
131 int
sys_osf_gettimeofday(tcp)132 sys_osf_gettimeofday(tcp)
133 struct tcb *tcp;
134 {
135     if (exiting(tcp)) {
136 	if (syserror(tcp)) {
137 	    tprintf("%#lx, %#lx",
138 		    tcp->u_arg[0], tcp->u_arg[1]);
139 	    return 0;
140 	}
141 	printtv32(tcp, tcp->u_arg[0]);
142 #ifndef SVR4
143 	tprintf(", ");
144 	printtv32(tcp, tcp->u_arg[1]);
145 #endif /* !SVR4 */
146     }
147     return 0;
148 }
149 #endif
150 
151 int
sys_settimeofday(tcp)152 sys_settimeofday(tcp)
153 struct tcb *tcp;
154 {
155 	if (entering(tcp)) {
156 		printtv(tcp, tcp->u_arg[0]);
157 #ifndef SVR4
158 		tprintf(", ");
159 		printtv(tcp, tcp->u_arg[1]);
160 #endif /* !SVR4 */
161 	}
162 	return 0;
163 }
164 
165 #ifdef ALPHA
166 int
sys_osf_settimeofday(tcp)167 sys_osf_settimeofday(tcp)
168 struct tcb *tcp;
169 {
170     if (entering(tcp)) {
171 	printtv32(tcp, tcp->u_arg[0]);
172 #ifndef SVR4
173 	tprintf(", ");
174 	printtv32(tcp, tcp->u_arg[1]);
175 #endif /* !SVR4 */
176     }
177     return 0;
178 }
179 #endif
180 
181 int
sys_adjtime(tcp)182 sys_adjtime(tcp)
183 struct tcb *tcp;
184 {
185 	if (entering(tcp)) {
186 		printtv(tcp, tcp->u_arg[0]);
187 		tprintf(", ");
188 	} else {
189 		if (syserror(tcp))
190 			tprintf("%#lx", tcp->u_arg[1]);
191 		else
192 			printtv(tcp, tcp->u_arg[1]);
193 	}
194 	return 0;
195 }
196 
197 static const struct xlat which[] = {
198 	{ ITIMER_REAL,	"ITIMER_REAL"	},
199 	{ ITIMER_VIRTUAL,"ITIMER_VIRTUAL"},
200 	{ ITIMER_PROF,	"ITIMER_PROF"	},
201 	{ 0,		NULL		},
202 };
203 
204 static void
printitv(tcp,addr)205 printitv(tcp, addr)
206 struct tcb *tcp;
207 long addr;
208 {
209 	struct itimerval itv;
210 
211 	if (addr == 0)
212 		tprintf("NULL");
213 	else if (!verbose(tcp))
214 		tprintf("%#lx", addr);
215 	else if (umove(tcp, addr, &itv) < 0)
216 		tprintf("{...}");
217 	else {
218 		tprintf("{it_interval={%lu, %lu}, it_value={%lu, %lu}}",
219 		(long) itv.it_interval.tv_sec, (long) itv.it_interval.tv_usec,
220 		(long) itv.it_value.tv_sec, (long) itv.it_value.tv_usec);
221 	}
222 }
223 
224 
225 #ifdef ALPHA
226 static void
printitv32(tcp,addr)227 printitv32(tcp, addr)
228 struct tcb *tcp;
229 long addr;
230 {
231     struct itimerval32
232     {
233 	struct timeval32 it_interval;
234 	struct timeval32 it_value;
235     } itv;
236 
237     if (addr == 0)
238 	tprintf("NULL");
239     else if (!verbose(tcp))
240 	tprintf("%#lx", addr);
241     else if (umove(tcp, addr, &itv) < 0)
242 	tprintf("{...}");
243     else {
244 	tprintf("{it_interval={%u, %u}, it_value={%u, %u}}",
245 		itv.it_interval.tv_sec, itv.it_interval.tv_usec,
246 		itv.it_value.tv_sec, itv.it_value.tv_usec);
247     }
248 }
249 #endif
250 
251 int
sys_getitimer(tcp)252 sys_getitimer(tcp)
253 struct tcb *tcp;
254 {
255 	if (entering(tcp)) {
256 		printxval(which, tcp->u_arg[0], "ITIMER_???");
257 		tprintf(", ");
258 	} else {
259 		if (syserror(tcp))
260 			tprintf("%#lx", tcp->u_arg[1]);
261 		else
262 			printitv(tcp, tcp->u_arg[1]);
263 	}
264 	return 0;
265 }
266 
267 
268 #ifdef ALPHA
269 int
sys_osf_getitimer(tcp)270 sys_osf_getitimer(tcp)
271 struct tcb *tcp;
272 {
273     if (entering(tcp)) {
274 	printxval(which, tcp->u_arg[0], "ITIMER_???");
275 	tprintf(", ");
276     } else {
277 	if (syserror(tcp))
278 	    tprintf("%#lx", tcp->u_arg[1]);
279 	else
280 	    printitv32(tcp, tcp->u_arg[1]);
281     }
282     return 0;
283 }
284 #endif
285 
286 int
sys_setitimer(tcp)287 sys_setitimer(tcp)
288 struct tcb *tcp;
289 {
290 	if (entering(tcp)) {
291 		printxval(which, tcp->u_arg[0], "ITIMER_???");
292 		tprintf(", ");
293 		printitv(tcp, tcp->u_arg[1]);
294 		tprintf(", ");
295 	} else {
296 		if (syserror(tcp))
297 			tprintf("%#lx", tcp->u_arg[2]);
298 		else
299 			printitv(tcp, tcp->u_arg[2]);
300 	}
301 	return 0;
302 }
303 
304 #ifdef ALPHA
305 int
sys_osf_setitimer(tcp)306 sys_osf_setitimer(tcp)
307 struct tcb *tcp;
308 {
309     if (entering(tcp)) {
310 	printxval(which, tcp->u_arg[0], "ITIMER_???");
311 	tprintf(", ");
312 	printitv32(tcp, tcp->u_arg[1]);
313 	tprintf(", ");
314     } else {
315 	if (syserror(tcp))
316 	    tprintf("%#lx", tcp->u_arg[2]);
317 	else
318 	    printitv32(tcp, tcp->u_arg[2]);
319     }
320     return 0;
321 }
322 #endif
323 
324 #ifdef LINUX
325 
326 int
sys_adjtimex(tcp)327 sys_adjtimex(tcp)
328 struct tcb *tcp;
329 {
330 	struct timex txc;
331 
332 	if (exiting(tcp)) {
333 		if (tcp->u_arg[0] == 0)
334 			tprintf("NULL");
335 		else if (syserror(tcp) || !verbose(tcp))
336 			tprintf("%#lx", tcp->u_arg[0]);
337 		else if (umove(tcp, tcp->u_arg[0], &txc) < 0)
338 			tprintf("{...}");
339 		else {
340 #if LINUX_VERSION_CODE < 66332
341 			tprintf("{mode=%d, offset=%ld, frequency=%ld, ",
342 				txc.mode, txc.offset, txc.frequency);
343 			tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
344 				txc.maxerror, txc.esterror, txc.status);
345 			tprintf("time_constant=%ld, precision=%lu, ",
346 				txc.time_constant, txc.precision);
347 			tprintf("tolerance=%ld, time={%lu, %lu}}",
348 				txc.tolerance, (long) txc.time.tv_sec,
349 				(long) txc.time.tv_usec);
350 #else
351 			tprintf("{modes=%d, offset=%ld, freq=%ld, ",
352 				txc.modes, txc.offset, txc.freq);
353 			tprintf("maxerror=%ld, esterror=%lu, status=%u, ",
354 				txc.maxerror, txc.esterror, txc.status);
355 			tprintf("constant=%ld, precision=%lu, ",
356 				txc.constant, txc.precision);
357 			tprintf("tolerance=%ld, time={%lu, %lu}}",
358 				txc.tolerance, (long) txc.time.tv_sec,
359 				(long) txc.time.tv_usec);
360 			/* there's a bunch of other stuff, but it's not
361 			 * worth the time or the trouble to include */
362 #endif
363 		}
364 	}
365 	return 0;
366 }
367 
368 static const struct xlat clockflags[] = {
369   { TIMER_ABSTIME, "TIMER_ABSTIME" },
370   { 0,             NULL }
371 };
372 
373 static const struct xlat clocknames[] = {
374 #ifdef CLOCK_REALTIME
375   { CLOCK_REALTIME, "CLOCK_REALTIME" },
376 #endif
377 #ifdef CLOCK_MONOTONIC
378   { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" },
379 #endif
380   { 0,             NULL }
381 };
382 
383 int
sys_clock_settime(tcp)384 sys_clock_settime(tcp)
385 struct tcb *tcp;
386 {
387 	if (entering(tcp)) {
388 		printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
389 		tprintf(", ");
390 		printtv(tcp, tcp->u_arg[1]);
391 	}
392 	return 0;
393 }
394 
395 int
sys_clock_gettime(tcp)396 sys_clock_gettime(tcp)
397 struct tcb *tcp;
398 {
399 	if (entering(tcp)) {
400 		printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
401 		tprintf(", ");
402 	} else {
403 		if (syserror(tcp))
404 			tprintf("%#lx", tcp->u_arg[1]);
405 		else
406 			printtv(tcp, tcp->u_arg[1]);
407 	}
408 	return 0;
409 }
410 
411 int
sys_clock_nanosleep(tcp)412 sys_clock_nanosleep(tcp)
413 struct tcb *tcp;
414 {
415 	if (entering(tcp)) {
416 		printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
417 		tprintf(", ");
418 		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
419 		tprintf(", ");
420 		printtv(tcp, tcp->u_arg[2]);
421 		tprintf(", ");
422 	} else {
423 		if (syserror(tcp))
424 			tprintf("%#lx", tcp->u_arg[3]);
425 		else
426 			printtv(tcp, tcp->u_arg[3]);
427 	}
428 	return 0;
429 }
430 
431 #ifndef SIGEV_THREAD_ID
432 # define SIGEV_THREAD_ID 4
433 #endif
434 static const struct xlat sigev_value[] = {
435 	{ SIGEV_SIGNAL+1, "SIGEV_SIGNAL" },
436 	{ SIGEV_NONE+1, "SIGEV_NONE" },
437 	{ SIGEV_THREAD+1, "SIGEV_THREAD" },
438 	{ SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" },
439 	{ 0, NULL }
440 };
441 
442 void
printsigevent(tcp,arg)443 printsigevent(tcp, arg)
444 struct tcb *tcp;
445 long arg;
446 {
447 	struct sigevent sev;
448 	if (umove (tcp, arg, &sev) < 0)
449 		tprintf("{...}");
450 	else {
451 		tprintf("{%p, ", sev.sigev_value.sival_ptr);
452 		if (sev.sigev_notify == SIGEV_SIGNAL)
453 			tprintf("%s, ", signame(sev.sigev_signo));
454 		else
455 			tprintf("%u, ", sev.sigev_signo);
456 		printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???");
457 		tprintf(", ");
458 		if (sev.sigev_notify == SIGEV_THREAD_ID)
459 			/* _pad[0] is the _tid field which might not be
460 			   present in the userlevel definition of the
461 			   struct.  */
462 			tprintf("{%d}", sev._sigev_un._pad[0]);
463 		else if (sev.sigev_notify == SIGEV_THREAD)
464 			tprintf("{%p, %p}", sev.sigev_notify_function,
465 				sev.sigev_notify_attributes);
466 		else
467 			tprintf("{...}");
468 		tprintf("}");
469 	}
470 }
471 
472 int
sys_timer_create(tcp)473 sys_timer_create(tcp)
474 struct tcb *tcp;
475 {
476 	if (entering(tcp)) {
477 		printxval(clocknames, tcp->u_arg[0], "CLOCK_???");
478 		tprintf(", ");
479 		printsigevent(tcp, tcp->u_arg[1]);
480 		tprintf(", ");
481 	} else {
482 		if (syserror(tcp))
483 			tprintf("%#lx", tcp->u_arg[2]);
484 		else {
485 			void *p;
486 			umove(tcp, tcp->u_arg[2], &p);
487 			tprintf("{%p}", p);
488 		}
489 	}
490 	return 0;
491 }
492 
493 int
sys_timer_settime(tcp)494 sys_timer_settime(tcp)
495 struct tcb *tcp;
496 {
497 	if (entering(tcp)) {
498 		tprintf("%#lx, ", tcp->u_arg[0]);
499 		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
500 		tprintf(", ");
501 		printitv(tcp, tcp->u_arg[2]);
502 		tprintf(", ");
503 	} else {
504 		if (syserror(tcp))
505 			tprintf("%#lx", tcp->u_arg[3]);
506 		else
507 			printitv(tcp, tcp->u_arg[3]);
508 	}
509 	return 0;
510 }
511 
512 int
sys_timer_gettime(tcp)513 sys_timer_gettime(tcp)
514 struct tcb *tcp;
515 {
516 	if (entering(tcp)) {
517 		tprintf("%#lx, ", tcp->u_arg[0]);
518 	} else {
519 		if (syserror(tcp))
520 			tprintf("%#lx", tcp->u_arg[1]);
521 		else
522 			printitv(tcp, tcp->u_arg[1]);
523 	}
524 	return 0;
525 }
526 
527 static void
print_rtc(tcp,rt)528 print_rtc(tcp, rt)
529 struct tcb *tcp;
530 const struct rtc_time *rt;
531 {
532 	tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, "
533 		"tm_mday=%d, tm_mon=%d, tm_year=%d, ",
534 		rt->tm_sec, rt->tm_min, rt->tm_hour,
535 		rt->tm_mday, rt->tm_mon, rt->tm_year);
536 	if (!abbrev(tcp))
537 		tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
538 			rt->tm_wday, rt->tm_yday, rt->tm_isdst);
539 	else
540 		tprintf("...}");
541 }
542 
543 int
rtc_ioctl(tcp,code,arg)544 rtc_ioctl(tcp, code, arg)
545 struct tcb *tcp;
546 long code;
547 long arg;
548 {
549 	switch (code) {
550 	case RTC_ALM_SET:
551 	case RTC_SET_TIME:
552 		if (entering(tcp)) {
553 			struct rtc_time rt;
554 			if (umove(tcp, arg, &rt) < 0)
555 				tprintf(", %#lx", arg);
556 			else {
557 				tprintf(", ");
558 				print_rtc(tcp, &rt);
559 			}
560 		}
561 		break;
562 	case RTC_ALM_READ:
563 	case RTC_RD_TIME:
564 		if (exiting(tcp)) {
565 			struct rtc_time rt;
566 			if (syserror(tcp) || umove(tcp, arg, &rt) < 0)
567 				tprintf(", %#lx", arg);
568 			else {
569 				tprintf(", ");
570 				print_rtc(tcp, &rt);
571 			}
572 		}
573 		break;
574 	case RTC_IRQP_SET:
575 	case RTC_EPOCH_SET:
576 		if (entering(tcp))
577 			tprintf(", %lu", arg);
578 		break;
579 	case RTC_IRQP_READ:
580 	case RTC_EPOCH_READ:
581 		if (exiting(tcp))
582 			tprintf(", %lu", arg);
583 		break;
584 	case RTC_WKALM_SET:
585 		if (entering(tcp)) {
586 			struct rtc_wkalrm wk;
587 			if (umove(tcp, arg, &wk) < 0)
588 				tprintf(", %#lx", arg);
589 			else {
590 				tprintf(", {enabled=%d, pending=%d, ",
591 					wk.enabled, wk.pending);
592 				print_rtc(tcp, &wk.time);
593 				tprintf("}");
594 			}
595 		}
596 		break;
597 	case RTC_WKALM_RD:
598 		if (exiting(tcp)) {
599 			struct rtc_wkalrm wk;
600 			if (syserror(tcp) || umove(tcp, arg, &wk) < 0)
601 				tprintf(", %#lx", arg);
602 			else {
603 				tprintf(", {enabled=%d, pending=%d, ",
604 					wk.enabled, wk.pending);
605 				print_rtc(tcp, &wk.time);
606 				tprintf("}");
607 			}
608 		}
609 		break;
610 	default:
611 		if (entering(tcp))
612 			tprintf(", %#lx", arg);
613 		break;
614 	}
615 	return 1;
616 }
617 #endif /* LINUX */
618