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