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