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