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#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 44#ifndef UTIME_NOW 45#define UTIME_NOW ((1l << 30) - 1l) 46#endif 47#ifndef UTIME_OMIT 48#define UTIME_OMIT ((1l << 30) - 2l) 49#endif 50#endif /* LINUX */ 51 52struct timeval32 53{ 54 u_int32_t tv_sec, tv_usec; 55}; 56 57static void 58tprint_timeval32(struct tcb *tcp, const struct timeval32 *tv) 59{ 60 tprintf("{%u, %u}", tv->tv_sec, tv->tv_usec); 61} 62 63static void 64tprint_timeval(struct tcb *tcp, const struct timeval *tv) 65{ 66 tprintf("{%lu, %lu}", 67 (unsigned long) tv->tv_sec, (unsigned long) tv->tv_usec); 68} 69 70void 71printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special) 72{ 73 if (addr == 0) 74 tprintf("NULL"); 75 else if (!verbose(tcp)) 76 tprintf("%#lx", addr); 77 else { 78 int rc; 79 80 if (bitness == BITNESS_32 81#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 82 || personality_wordsize[current_personality] == 4 83#endif 84 ) 85 { 86 struct timeval32 tv; 87 88 if ((rc = umove(tcp, addr, &tv)) >= 0) { 89 if (special && tv.tv_sec == 0 && 90 tv.tv_usec == UTIME_NOW) 91 tprintf("UTIME_NOW"); 92 else if (special && tv.tv_sec == 0 && 93 tv.tv_usec == UTIME_OMIT) 94 tprintf("UTIME_OMIT"); 95 else 96 tprint_timeval32(tcp, &tv); 97 } 98 } else { 99 struct timeval tv; 100 101 if ((rc = umove(tcp, addr, &tv)) >= 0) { 102 if (special && tv.tv_sec == 0 && 103 tv.tv_usec == UTIME_NOW) 104 tprintf("UTIME_NOW"); 105 else if (special && tv.tv_sec == 0 && 106 tv.tv_usec == UTIME_OMIT) 107 tprintf("UTIME_OMIT"); 108 else 109 tprint_timeval(tcp, &tv); 110 } 111 } 112 if (rc < 0) 113 tprintf("{...}"); 114 } 115} 116 117void 118sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf) 119{ 120 if (addr == 0) 121 strcpy(buf, "NULL"); 122 else if (!verbose(tcp)) 123 sprintf(buf, "%#lx", addr); 124 else { 125 int rc; 126 127 if (bitness == BITNESS_32 128#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 129 || personality_wordsize[current_personality] == 4 130#endif 131 ) 132 { 133 struct timeval32 tv; 134 135 if ((rc = umove(tcp, addr, &tv)) >= 0) 136 sprintf(buf, "{%u, %u}", 137 tv.tv_sec, tv.tv_usec); 138 } else { 139 struct timeval tv; 140 141 if ((rc = umove(tcp, addr, &tv)) >= 0) 142 sprintf(buf, "{%lu, %lu}", 143 (unsigned long) tv.tv_sec, 144 (unsigned long) tv.tv_usec); 145 } 146 if (rc < 0) 147 strcpy(buf, "{...}"); 148 } 149} 150 151void print_timespec(struct tcb *tcp, long addr) 152{ 153 if (addr == 0) 154 tprintf("NULL"); 155 else if (!verbose(tcp)) 156 tprintf("%#lx", addr); 157 else { 158 int rc; 159 160#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 161 if (personality_wordsize[current_personality] == 4) { 162 struct timeval32 tv; 163 164 if ((rc = umove(tcp, addr, &tv)) >= 0) 165 tprintf("{%u, %u}", 166 tv.tv_sec, tv.tv_usec); 167 } else 168#endif 169 { 170 struct timespec ts; 171 172 if ((rc = umove(tcp, addr, &ts)) >= 0) 173 tprintf("{%lu, %lu}", 174 (unsigned long) ts.tv_sec, 175 (unsigned long) ts.tv_nsec); 176 } 177 if (rc < 0) 178 tprintf("{...}"); 179 } 180} 181 182void sprint_timespec(char *buf, struct tcb *tcp, long addr) 183{ 184 if (addr == 0) 185 strcpy(buf, "NULL"); 186 else if (!verbose(tcp)) 187 sprintf(buf, "%#lx", addr); 188 else { 189 int rc; 190 191#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 192 if (personality_wordsize[current_personality] == 4) { 193 struct timeval32 tv; 194 195 if ((rc = umove(tcp, addr, &tv)) >= 0) 196 sprintf(buf, "{%u, %u}", 197 tv.tv_sec, tv.tv_usec); 198 } else 199#endif 200 { 201 struct timespec ts; 202 203 if ((rc = umove(tcp, addr, &ts)) >= 0) 204 sprintf(buf, "{%lu, %lu}", 205 (unsigned long) ts.tv_sec, 206 (unsigned long) ts.tv_nsec); 207 } 208 if (rc < 0) 209 strcpy(buf, "{...}"); 210 } 211} 212 213int 214sys_time(tcp) 215struct tcb *tcp; 216{ 217 if (exiting(tcp)) { 218#ifndef SVR4 219 printnum(tcp, tcp->u_arg[0], "%ld"); 220#endif /* SVR4 */ 221 } 222 return 0; 223} 224 225int 226sys_stime(tcp) 227struct tcb *tcp; 228{ 229 if (exiting(tcp)) { 230 printnum(tcp, tcp->u_arg[0], "%ld"); 231 } 232 return 0; 233} 234 235int 236sys_gettimeofday(tcp) 237struct tcb *tcp; 238{ 239 if (exiting(tcp)) { 240 if (syserror(tcp)) { 241 tprintf("%#lx, %#lx", 242 tcp->u_arg[0], tcp->u_arg[1]); 243 return 0; 244 } 245 printtv(tcp, tcp->u_arg[0]); 246#ifndef SVR4 247 tprintf(", "); 248 printtv(tcp, tcp->u_arg[1]); 249#endif /* !SVR4 */ 250 } 251 return 0; 252} 253 254 255#ifdef ALPHA 256int 257sys_osf_gettimeofday(tcp) 258struct tcb *tcp; 259{ 260 if (exiting(tcp)) { 261 if (syserror(tcp)) { 262 tprintf("%#lx, %#lx", tcp->u_arg[0], tcp->u_arg[1]); 263 return 0; 264 } 265 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); 266#ifndef SVR4 267 tprintf(", "); 268 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); 269#endif /* !SVR4 */ 270 } 271 return 0; 272} 273#endif 274 275int 276sys_settimeofday(tcp) 277struct tcb *tcp; 278{ 279 if (entering(tcp)) { 280 printtv(tcp, tcp->u_arg[0]); 281#ifndef SVR4 282 tprintf(", "); 283 printtv(tcp, tcp->u_arg[1]); 284#endif /* !SVR4 */ 285 } 286 return 0; 287} 288 289#ifdef ALPHA 290int 291sys_osf_settimeofday(tcp) 292struct tcb *tcp; 293{ 294 if (entering(tcp)) { 295 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0); 296#ifndef SVR4 297 tprintf(", "); 298 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0); 299#endif /* !SVR4 */ 300 } 301 return 0; 302} 303#endif 304 305int 306sys_adjtime(tcp) 307struct tcb *tcp; 308{ 309 if (entering(tcp)) { 310 printtv(tcp, tcp->u_arg[0]); 311 tprintf(", "); 312 } else { 313 if (syserror(tcp)) 314 tprintf("%#lx", tcp->u_arg[1]); 315 else 316 printtv(tcp, tcp->u_arg[1]); 317 } 318 return 0; 319} 320 321int 322sys_nanosleep(struct tcb *tcp) 323{ 324 if (entering(tcp)) { 325 print_timespec(tcp, tcp->u_arg[0]); 326 tprintf(", "); 327 } else { 328 if (!tcp->u_arg[1] || is_restart_error(tcp)) 329 print_timespec(tcp, tcp->u_arg[1]); 330 else 331 tprintf("%#lx", tcp->u_arg[1]); 332 } 333 return 0; 334} 335 336static const struct xlat which[] = { 337 { ITIMER_REAL, "ITIMER_REAL" }, 338 { ITIMER_VIRTUAL,"ITIMER_VIRTUAL"}, 339 { ITIMER_PROF, "ITIMER_PROF" }, 340 { 0, NULL }, 341}; 342 343static void 344printitv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness) 345{ 346 if (addr == 0) 347 tprintf("NULL"); 348 else if (!verbose(tcp)) 349 tprintf("%#lx", addr); 350 else { 351 int rc; 352 353 if (bitness == BITNESS_32 354#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 355 || personality_wordsize[current_personality] == 4 356#endif 357 ) 358 { 359 struct { 360 struct timeval32 it_interval, it_value; 361 } itv; 362 363 if ((rc = umove(tcp, addr, &itv)) >= 0) { 364 tprintf("{it_interval="); 365 tprint_timeval32(tcp, &itv.it_interval); 366 tprintf(", it_value="); 367 tprint_timeval32(tcp, &itv.it_value); 368 tprintf("}"); 369 } 370 } else { 371 struct itimerval itv; 372 373 if ((rc = umove(tcp, addr, &itv)) >= 0) { 374 tprintf("{it_interval="); 375 tprint_timeval(tcp, &itv.it_interval); 376 tprintf(", it_value="); 377 tprint_timeval(tcp, &itv.it_value); 378 tprintf("}"); 379 } 380 } 381 if (rc < 0) 382 tprintf("{...}"); 383 } 384} 385 386#define printitv(tcp, addr) \ 387 printitv_bitness((tcp), (addr), BITNESS_CURRENT) 388 389int 390sys_getitimer(tcp) 391struct tcb *tcp; 392{ 393 if (entering(tcp)) { 394 printxval(which, tcp->u_arg[0], "ITIMER_???"); 395 tprintf(", "); 396 } else { 397 if (syserror(tcp)) 398 tprintf("%#lx", tcp->u_arg[1]); 399 else 400 printitv(tcp, tcp->u_arg[1]); 401 } 402 return 0; 403} 404 405 406#ifdef ALPHA 407int 408sys_osf_getitimer(tcp) 409struct tcb *tcp; 410{ 411 if (entering(tcp)) { 412 printxval(which, tcp->u_arg[0], "ITIMER_???"); 413 tprintf(", "); 414 } else { 415 if (syserror(tcp)) 416 tprintf("%#lx", tcp->u_arg[1]); 417 else 418 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); 419 } 420 return 0; 421} 422#endif 423 424int 425sys_setitimer(tcp) 426struct tcb *tcp; 427{ 428 if (entering(tcp)) { 429 printxval(which, tcp->u_arg[0], "ITIMER_???"); 430 tprintf(", "); 431 printitv(tcp, tcp->u_arg[1]); 432 tprintf(", "); 433 } else { 434 if (syserror(tcp)) 435 tprintf("%#lx", tcp->u_arg[2]); 436 else 437 printitv(tcp, tcp->u_arg[2]); 438 } 439 return 0; 440} 441 442#ifdef ALPHA 443int 444sys_osf_setitimer(tcp) 445struct tcb *tcp; 446{ 447 if (entering(tcp)) { 448 printxval(which, tcp->u_arg[0], "ITIMER_???"); 449 tprintf(", "); 450 printitv_bitness(tcp, tcp->u_arg[1], BITNESS_32); 451 tprintf(", "); 452 } else { 453 if (syserror(tcp)) 454 tprintf("%#lx", tcp->u_arg[2]); 455 else 456 printitv_bitness(tcp, tcp->u_arg[2], BITNESS_32); 457 } 458 return 0; 459} 460#endif 461 462#ifdef LINUX 463 464static const struct xlat adjtimex_modes[] = { 465 { 0, "0" }, 466#ifdef ADJ_OFFSET 467 { ADJ_OFFSET, "ADJ_OFFSET" }, 468#endif 469#ifdef ADJ_FREQUENCY 470 { ADJ_FREQUENCY, "ADJ_FREQUENCY" }, 471#endif 472#ifdef ADJ_MAXERROR 473 { ADJ_MAXERROR, "ADJ_MAXERROR" }, 474#endif 475#ifdef ADJ_ESTERROR 476 { ADJ_ESTERROR, "ADJ_ESTERROR" }, 477#endif 478#ifdef ADJ_STATUS 479 { ADJ_STATUS, "ADJ_STATUS" }, 480#endif 481#ifdef ADJ_TIMECONST 482 { ADJ_TIMECONST, "ADJ_TIMECONST" }, 483#endif 484#ifdef ADJ_TICK 485 { ADJ_TICK, "ADJ_TICK" }, 486#endif 487#ifdef ADJ_OFFSET_SINGLESHOT 488 { ADJ_OFFSET_SINGLESHOT, "ADJ_OFFSET_SINGLESHOT" }, 489#endif 490 { 0, NULL } 491}; 492 493static const struct xlat adjtimex_status[] = { 494#ifdef STA_PLL 495 { STA_PLL, "STA_PLL" }, 496#endif 497#ifdef STA_PPSFREQ 498 { STA_PPSFREQ, "STA_PPSFREQ" }, 499#endif 500#ifdef STA_PPSTIME 501 { STA_PPSTIME, "STA_PPSTIME" }, 502#endif 503#ifdef STA_FLL 504 { STA_FLL, "STA_FLL" }, 505#endif 506#ifdef STA_INS 507 { STA_INS, "STA_INS" }, 508#endif 509#ifdef STA_DEL 510 { STA_DEL, "STA_DEL" }, 511#endif 512#ifdef STA_UNSYNC 513 { STA_UNSYNC, "STA_UNSYNC" }, 514#endif 515#ifdef STA_FREQHOLD 516 { STA_FREQHOLD, "STA_FREQHOLD" }, 517#endif 518#ifdef STA_PPSSIGNAL 519 { STA_PPSSIGNAL, "STA_PPSSIGNAL" }, 520#endif 521#ifdef STA_PPSJITTER 522 { STA_PPSJITTER, "STA_PPSJITTER" }, 523#endif 524#ifdef STA_PPSWANDER 525 { STA_PPSWANDER, "STA_PPSWANDER" }, 526#endif 527#ifdef STA_PPSERROR 528 { STA_PPSERROR, "STA_PPSERROR" }, 529#endif 530#ifdef STA_CLOCKERR 531 { STA_CLOCKERR, "STA_CLOCKERR" }, 532#endif 533 { 0, NULL } 534}; 535 536static const struct xlat adjtimex_state[] = { 537#ifdef TIME_OK 538 { TIME_OK, "TIME_OK" }, 539#endif 540#ifdef TIME_INS 541 { TIME_INS, "TIME_INS" }, 542#endif 543#ifdef TIME_DEL 544 { TIME_DEL, "TIME_DEL" }, 545#endif 546#ifdef TIME_OOP 547 { TIME_OOP, "TIME_OOP" }, 548#endif 549#ifdef TIME_WAIT 550 { TIME_WAIT, "TIME_WAIT" }, 551#endif 552#ifdef TIME_ERROR 553 { TIME_ERROR, "TIME_ERROR" }, 554#endif 555 { 0, NULL } 556}; 557 558#if SUPPORTED_PERSONALITIES > 1 559static int 560tprint_timex32(struct tcb *tcp, long addr) 561{ 562 struct { 563 unsigned int modes; 564 int offset; 565 int freq; 566 int maxerror; 567 int esterror; 568 int status; 569 int constant; 570 int precision; 571 int tolerance; 572 struct timeval32 time; 573 int tick; 574 int ppsfreq; 575 int jitter; 576 int shift; 577 int stabil; 578 int jitcnt; 579 int calcnt; 580 int errcnt; 581 int stbcnt; 582 } tx; 583 584 if (umove(tcp, addr, &tx) < 0) 585 return -1; 586 587 tprintf("{modes="); 588 printflags(adjtimex_modes, tx.modes, "ADJ_???"); 589 tprintf(", offset=%d, freq=%d, maxerror=%d, ", 590 tx.offset, tx.freq, tx.maxerror); 591 tprintf("esterror=%u, status=", tx.esterror); 592 printflags(adjtimex_status, tx.status, "STA_???"); 593 tprintf(", constant=%d, precision=%u, ", 594 tx.constant, tx.precision); 595 tprintf("tolerance=%d, time=", tx.tolerance); 596 tprint_timeval32(tcp, &tx.time); 597 tprintf(", tick=%d, ppsfreq=%d, jitter=%d", 598 tx.tick, tx.ppsfreq, tx.jitter); 599 tprintf(", shift=%d, stabil=%d, jitcnt=%d", 600 tx.shift, tx.stabil, tx.jitcnt); 601 tprintf(", calcnt=%d, errcnt=%d, stbcnt=%d", 602 tx.calcnt, tx.errcnt, tx.stbcnt); 603 tprintf("}"); 604 return 0; 605} 606#endif /* SUPPORTED_PERSONALITIES > 1 */ 607 608static int 609tprint_timex(struct tcb *tcp, long addr) 610{ 611 struct timex tx; 612 613#if SUPPORTED_PERSONALITIES > 1 614 if (personality_wordsize[current_personality] == 4) 615 return tprint_timex32(tcp, addr); 616#endif 617 if (umove(tcp, addr, &tx) < 0) 618 return -1; 619 620#if LINUX_VERSION_CODE < 66332 621 tprintf("{mode=%d, offset=%ld, frequency=%ld, ", 622 tx.mode, tx.offset, tx.frequency); 623 tprintf("maxerror=%ld, esterror=%lu, status=%u, ", 624 tx.maxerror, tx.esterror, tx.status); 625 tprintf("time_constant=%ld, precision=%lu, ", 626 tx.time_constant, tx.precision); 627 tprintf("tolerance=%ld, time=", tx.tolerance); 628 tprint_timeval(tcp, &tx.time); 629#else 630 tprintf("{modes="); 631 printflags(adjtimex_modes, tx.modes, "ADJ_???"); 632 tprintf(", offset=%ld, freq=%ld, maxerror=%ld, ", 633 tx.offset, tx.freq, tx.maxerror); 634 tprintf("esterror=%lu, status=", tx.esterror); 635 printflags(adjtimex_status, tx.status, "STA_???"); 636 tprintf(", constant=%ld, precision=%lu, ", 637 tx.constant, tx.precision); 638 tprintf("tolerance=%ld, time=", tx.tolerance); 639 tprint_timeval(tcp, &tx.time); 640 tprintf(", tick=%ld, ppsfreq=%ld, jitter=%ld", 641 tx.tick, tx.ppsfreq, tx.jitter); 642 tprintf(", shift=%d, stabil=%ld, jitcnt=%ld", 643 tx.shift, tx.stabil, tx.jitcnt); 644 tprintf(", calcnt=%ld, errcnt=%ld, stbcnt=%ld", 645 tx.calcnt, tx.errcnt, tx.stbcnt); 646#endif 647 tprintf("}"); 648 return 0; 649} 650 651int 652sys_adjtimex(struct tcb *tcp) 653{ 654 if (exiting(tcp)) { 655 if (tcp->u_arg[0] == 0) 656 tprintf("NULL"); 657 else if (syserror(tcp) || !verbose(tcp)) 658 tprintf("%#lx", tcp->u_arg[0]); 659 else if (tprint_timex(tcp, tcp->u_arg[0]) < 0) 660 tprintf("{...}"); 661 if (syserror(tcp)) 662 return 0; 663 tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval); 664 if (tcp->auxstr) 665 return RVAL_STR; 666 } 667 return 0; 668} 669 670static const struct xlat clockflags[] = { 671 { TIMER_ABSTIME, "TIMER_ABSTIME" }, 672 { 0, NULL } 673}; 674 675static const struct xlat clocknames[] = { 676#ifdef CLOCK_REALTIME 677 { CLOCK_REALTIME, "CLOCK_REALTIME" }, 678#endif 679#ifdef CLOCK_MONOTONIC 680 { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, 681#endif 682#ifdef CLOCK_PROCESS_CPUTIME_ID 683 { CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID" }, 684#endif 685#ifdef CLOCK_THREAD_CPUTIME_ID 686 { CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID" }, 687#endif 688#ifdef CLOCK_MONOTONIC_RAW 689 { CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW" }, 690#endif 691#ifdef CLOCK_REALTIME_COARSE 692 { CLOCK_REALTIME_COARSE, "CLOCK_REALTIME_COARSE" }, 693#endif 694#ifdef CLOCK_MONOTONIC_COARSE 695 { CLOCK_MONOTONIC_COARSE, "CLOCK_MONOTONIC_COARSE" }, 696#endif 697 { 0, NULL } 698}; 699 700int 701sys_clock_settime(tcp) 702struct tcb *tcp; 703{ 704 if (entering(tcp)) { 705 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 706 tprintf(", "); 707 printtv(tcp, tcp->u_arg[1]); 708 } 709 return 0; 710} 711 712int 713sys_clock_gettime(tcp) 714struct tcb *tcp; 715{ 716 if (entering(tcp)) { 717 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 718 tprintf(", "); 719 } else { 720 if (syserror(tcp)) 721 tprintf("%#lx", tcp->u_arg[1]); 722 else 723 printtv(tcp, tcp->u_arg[1]); 724 } 725 return 0; 726} 727 728int 729sys_clock_nanosleep(tcp) 730struct tcb *tcp; 731{ 732 if (entering(tcp)) { 733 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 734 tprintf(", "); 735 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 736 tprintf(", "); 737 printtv(tcp, tcp->u_arg[2]); 738 tprintf(", "); 739 } else { 740 if (syserror(tcp)) 741 tprintf("%#lx", tcp->u_arg[3]); 742 else 743 printtv(tcp, tcp->u_arg[3]); 744 } 745 return 0; 746} 747 748#ifndef SIGEV_THREAD_ID 749# define SIGEV_THREAD_ID 4 750#endif 751static const struct xlat sigev_value[] = { 752 { SIGEV_SIGNAL+1, "SIGEV_SIGNAL" }, 753 { SIGEV_NONE+1, "SIGEV_NONE" }, 754 { SIGEV_THREAD+1, "SIGEV_THREAD" }, 755 { SIGEV_THREAD_ID+1, "SIGEV_THREAD_ID" }, 756 { 0, NULL } 757}; 758 759#if SUPPORTED_PERSONALITIES > 1 760static void 761printsigevent32(struct tcb *tcp, long arg) 762{ 763 struct { 764 int sigev_value; 765 int sigev_signo; 766 int sigev_notify; 767 768 union { 769 int tid; 770 struct { 771 int function, attribute; 772 } thread; 773 } un; 774 } sev; 775 776 if (umove(tcp, arg, &sev) < 0) 777 tprintf("{...}"); 778 else { 779 tprintf("{%#x, ", sev.sigev_value); 780 if (sev.sigev_notify == SIGEV_SIGNAL) 781 tprintf("%s, ", signame(sev.sigev_signo)); 782 else 783 tprintf("%u, ", sev.sigev_signo); 784 printxval(sigev_value, sev.sigev_notify + 1, "SIGEV_???"); 785 tprintf(", "); 786 if (sev.sigev_notify == SIGEV_THREAD_ID) 787 tprintf("{%d}", sev.un.tid); 788 else if (sev.sigev_notify == SIGEV_THREAD) 789 tprintf("{%#x, %#x}", 790 sev.un.thread.function, 791 sev.un.thread.attribute); 792 else 793 tprintf("{...}"); 794 tprintf("}"); 795 } 796} 797#endif 798 799void 800printsigevent(struct tcb *tcp, long arg) 801{ 802 struct sigevent sev; 803 804#if SUPPORTED_PERSONALITIES > 1 805 if (personality_wordsize[current_personality] == 4) 806 { 807 printsigevent32(tcp, arg); 808 return; 809 } 810#endif 811 if (umove (tcp, arg, &sev) < 0) 812 tprintf("{...}"); 813 else { 814 tprintf("{%p, ", sev.sigev_value.sival_ptr); 815 if (sev.sigev_notify == SIGEV_SIGNAL) 816 tprintf("%s, ", signame(sev.sigev_signo)); 817 else 818 tprintf("%u, ", sev.sigev_signo); 819 printxval(sigev_value, sev.sigev_notify+1, "SIGEV_???"); 820 tprintf(", "); 821 if (sev.sigev_notify == SIGEV_THREAD_ID) 822 /* _pad[0] is the _tid field which might not be 823 present in the userlevel definition of the 824 struct. */ 825 tprintf("{%d}", sev._sigev_un._pad[0]); 826 else if (sev.sigev_notify == SIGEV_THREAD) 827 tprintf("{%p, %p}", sev.sigev_notify_function, 828 sev.sigev_notify_attributes); 829 else 830 tprintf("{...}"); 831 tprintf("}"); 832 } 833} 834 835int 836sys_timer_create(tcp) 837struct tcb *tcp; 838{ 839 if (entering(tcp)) { 840 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 841 tprintf(", "); 842 printsigevent(tcp, tcp->u_arg[1]); 843 tprintf(", "); 844 } else { 845 void *p; 846 847 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &p) < 0) 848 tprintf("%#lx", tcp->u_arg[2]); 849 else 850 tprintf("{%p}", p); 851 } 852 return 0; 853} 854 855int 856sys_timer_settime(tcp) 857struct tcb *tcp; 858{ 859 if (entering(tcp)) { 860 tprintf("%#lx, ", tcp->u_arg[0]); 861 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 862 tprintf(", "); 863 printitv(tcp, tcp->u_arg[2]); 864 tprintf(", "); 865 } else { 866 if (syserror(tcp)) 867 tprintf("%#lx", tcp->u_arg[3]); 868 else 869 printitv(tcp, tcp->u_arg[3]); 870 } 871 return 0; 872} 873 874int 875sys_timer_gettime(tcp) 876struct tcb *tcp; 877{ 878 if (entering(tcp)) { 879 tprintf("%#lx, ", tcp->u_arg[0]); 880 } else { 881 if (syserror(tcp)) 882 tprintf("%#lx", tcp->u_arg[1]); 883 else 884 printitv(tcp, tcp->u_arg[1]); 885 } 886 return 0; 887} 888 889static void 890print_rtc(tcp, rt) 891struct tcb *tcp; 892const struct rtc_time *rt; 893{ 894 tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, " 895 "tm_mday=%d, tm_mon=%d, tm_year=%d, ", 896 rt->tm_sec, rt->tm_min, rt->tm_hour, 897 rt->tm_mday, rt->tm_mon, rt->tm_year); 898 if (!abbrev(tcp)) 899 tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}", 900 rt->tm_wday, rt->tm_yday, rt->tm_isdst); 901 else 902 tprintf("...}"); 903} 904 905int 906rtc_ioctl(tcp, code, arg) 907struct tcb *tcp; 908long code; 909long arg; 910{ 911 switch (code) { 912 case RTC_ALM_SET: 913 case RTC_SET_TIME: 914 if (entering(tcp)) { 915 struct rtc_time rt; 916 if (umove(tcp, arg, &rt) < 0) 917 tprintf(", %#lx", arg); 918 else { 919 tprintf(", "); 920 print_rtc(tcp, &rt); 921 } 922 } 923 break; 924 case RTC_ALM_READ: 925 case RTC_RD_TIME: 926 if (exiting(tcp)) { 927 struct rtc_time rt; 928 if (syserror(tcp) || umove(tcp, arg, &rt) < 0) 929 tprintf(", %#lx", arg); 930 else { 931 tprintf(", "); 932 print_rtc(tcp, &rt); 933 } 934 } 935 break; 936 case RTC_IRQP_SET: 937 case RTC_EPOCH_SET: 938 if (entering(tcp)) 939 tprintf(", %lu", arg); 940 break; 941 case RTC_IRQP_READ: 942 case RTC_EPOCH_READ: 943 if (exiting(tcp)) 944 tprintf(", %lu", arg); 945 break; 946 case RTC_WKALM_SET: 947 if (entering(tcp)) { 948 struct rtc_wkalrm wk; 949 if (umove(tcp, arg, &wk) < 0) 950 tprintf(", %#lx", arg); 951 else { 952 tprintf(", {enabled=%d, pending=%d, ", 953 wk.enabled, wk.pending); 954 print_rtc(tcp, &wk.time); 955 tprintf("}"); 956 } 957 } 958 break; 959 case RTC_WKALM_RD: 960 if (exiting(tcp)) { 961 struct rtc_wkalrm wk; 962 if (syserror(tcp) || umove(tcp, arg, &wk) < 0) 963 tprintf(", %#lx", arg); 964 else { 965 tprintf(", {enabled=%d, pending=%d, ", 966 wk.enabled, wk.pending); 967 print_rtc(tcp, &wk.time); 968 tprintf("}"); 969 } 970 } 971 break; 972 default: 973 if (entering(tcp)) 974 tprintf(", %#lx", arg); 975 break; 976 } 977 return 1; 978} 979 980#ifndef TFD_TIMER_ABSTIME 981#define TFD_TIMER_ABSTIME (1 << 0) 982#endif 983 984static const struct xlat timerfdflags[] = { 985 { TFD_TIMER_ABSTIME, "TFD_TIMER_ABSTIME" }, 986 { 0, NULL } 987}; 988 989int 990sys_timerfd(tcp) 991struct tcb *tcp; 992{ 993 if (entering(tcp)) { 994 /* It does not matter that the kernel uses itimerspec. */ 995 tprintf("%ld, ", tcp->u_arg[0]); 996 printxval(clocknames, tcp->u_arg[1], "CLOCK_???"); 997 tprintf(", "); 998 printflags(timerfdflags, tcp->u_arg[2], "TFD_???"); 999 tprintf(", "); 1000 printitv(tcp, tcp->u_arg[3]); 1001 } 1002 return 0; 1003} 1004 1005int 1006sys_timerfd_create(struct tcb *tcp) 1007{ 1008 if (entering(tcp)) { 1009 printxval(clocknames, tcp->u_arg[0], "CLOCK_???"); 1010 tprintf(", "); 1011 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 1012 } 1013 return 0; 1014} 1015 1016int 1017sys_timerfd_settime(struct tcb *tcp) 1018{ 1019 if (entering(tcp)) { 1020 printfd(tcp, tcp->u_arg[0]); 1021 tprintf(", "); 1022 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 1023 tprintf(", "); 1024 printitv(tcp, tcp->u_arg[2]); 1025 tprintf(", "); 1026 printitv(tcp, tcp->u_arg[3]); 1027 } 1028 return 0; 1029} 1030 1031int 1032sys_timerfd_gettime(struct tcb *tcp) 1033{ 1034 if (entering(tcp)) { 1035 printfd(tcp, tcp->u_arg[0]); 1036 tprintf(", "); 1037 printitv(tcp, tcp->u_arg[1]); 1038 } 1039 return 0; 1040} 1041 1042#endif /* LINUX */ 1043