desc.c revision 594527353359d9a6aad516992e09c393e11f3bd2
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 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "defs.h" 32#include <fcntl.h> 33#include <sys/file.h> 34#ifdef HAVE_SYS_EPOLL_H 35# include <sys/epoll.h> 36#endif 37#ifdef HAVE_LINUX_PERF_EVENT_H 38# include <linux/perf_event.h> 39#endif 40 41static const struct xlat fcntlcmds[] = { 42 XLAT(F_DUPFD), 43 XLAT(F_GETFD), 44 XLAT(F_SETFD), 45 XLAT(F_GETFL), 46 XLAT(F_SETFL), 47 XLAT(F_GETLK), 48 XLAT(F_SETLK), 49 XLAT(F_SETLKW), 50 XLAT(F_GETOWN), 51 XLAT(F_SETOWN), 52#ifdef F_RSETLK 53 XLAT(F_RSETLK), 54#endif 55#ifdef F_RSETLKW 56 XLAT(F_RSETLKW), 57#endif 58#ifdef F_RGETLK 59 XLAT(F_RGETLK), 60#endif 61#ifdef F_CNVT 62 XLAT(F_CNVT), 63#endif 64#ifdef F_SETSIG 65 XLAT(F_SETSIG), 66#endif 67#ifdef F_GETSIG 68 XLAT(F_GETSIG), 69#endif 70#ifdef F_CHKFL 71 XLAT(F_CHKFL), 72#endif 73#ifdef F_DUP2FD 74 XLAT(F_DUP2FD), 75#endif 76#ifdef F_ALLOCSP 77 XLAT(F_ALLOCSP), 78#endif 79#ifdef F_ISSTREAM 80 XLAT(F_ISSTREAM), 81#endif 82#ifdef F_PRIV 83 XLAT(F_PRIV), 84#endif 85#ifdef F_NPRIV 86 XLAT(F_NPRIV), 87#endif 88#ifdef F_QUOTACL 89 XLAT(F_QUOTACL), 90#endif 91#ifdef F_BLOCKS 92 XLAT(F_BLOCKS), 93#endif 94#ifdef F_BLKSIZE 95 XLAT(F_BLKSIZE), 96#endif 97#ifdef F_GETOWN 98 XLAT(F_GETOWN), 99#endif 100#ifdef F_SETOWN 101 XLAT(F_SETOWN), 102#endif 103#ifdef F_REVOKE 104 XLAT(F_REVOKE), 105#endif 106#ifdef F_SETLK 107 XLAT(F_SETLK), 108#endif 109#ifdef F_SETLKW 110 XLAT(F_SETLKW), 111#endif 112#ifdef F_FREESP 113 XLAT(F_FREESP), 114#endif 115#ifdef F_GETLK 116 XLAT(F_GETLK), 117#endif 118#ifdef F_SETLK64 119 XLAT(F_SETLK64), 120#endif 121#ifdef F_SETLKW64 122 XLAT(F_SETLKW64), 123#endif 124#ifdef F_FREESP64 125 XLAT(F_FREESP64), 126#endif 127#ifdef F_GETLK64 128 XLAT(F_GETLK64), 129#endif 130#ifdef F_SHARE 131 XLAT(F_SHARE), 132#endif 133#ifdef F_UNSHARE 134 XLAT(F_UNSHARE), 135#endif 136#ifdef F_SETLEASE 137 XLAT(F_SETLEASE), 138#endif 139#ifdef F_GETLEASE 140 XLAT(F_GETLEASE), 141#endif 142#ifdef F_NOTIFY 143 XLAT(F_NOTIFY), 144#endif 145#ifdef F_DUPFD_CLOEXEC 146 XLAT(F_DUPFD_CLOEXEC), 147#endif 148 XLAT_END 149}; 150 151static const struct xlat fdflags[] = { 152#ifdef FD_CLOEXEC 153 XLAT(FD_CLOEXEC), 154#endif 155 XLAT_END 156}; 157 158#ifdef LOCK_SH 159 160static const struct xlat flockcmds[] = { 161 XLAT(LOCK_SH), 162 XLAT(LOCK_EX), 163 XLAT(LOCK_NB), 164 XLAT(LOCK_UN), 165 XLAT_END 166}; 167 168#endif /* LOCK_SH */ 169 170static const struct xlat lockfcmds[] = { 171 XLAT(F_RDLCK), 172 XLAT(F_WRLCK), 173 XLAT(F_UNLCK), 174#ifdef F_EXLCK 175 XLAT(F_EXLCK), 176#endif 177#ifdef F_SHLCK 178 XLAT(F_SHLCK), 179#endif 180 XLAT_END 181}; 182 183#ifdef F_NOTIFY 184static const struct xlat notifyflags[] = { 185#ifdef DN_ACCESS 186 XLAT(DN_ACCESS), 187#endif 188#ifdef DN_MODIFY 189 XLAT(DN_MODIFY), 190#endif 191#ifdef DN_CREATE 192 XLAT(DN_CREATE), 193#endif 194#ifdef DN_DELETE 195 XLAT(DN_DELETE), 196#endif 197#ifdef DN_RENAME 198 XLAT(DN_RENAME), 199#endif 200#ifdef DN_ATTRIB 201 XLAT(DN_ATTRIB), 202#endif 203#ifdef DN_MULTISHOT 204 XLAT(DN_MULTISHOT), 205#endif 206 XLAT_END 207}; 208#endif 209 210static const struct xlat perf_event_open_flags[] = { 211#ifdef PERF_FLAG_FD_NO_GROUP 212 XLAT(PERF_FLAG_FD_NO_GROUP), 213#endif 214#ifdef PERF_FLAG_FD_OUTPUT 215 XLAT(PERF_FLAG_FD_OUTPUT), 216#endif 217#ifdef PERF_FLAG_PID_CGROUP 218 XLAT(PERF_FLAG_PID_CGROUP), 219#endif 220 XLAT_END 221}; 222 223#if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK 224# define HAVE_F_SETLK64 1 225#else 226# define HAVE_F_SETLK64 0 227#endif 228 229#if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW 230# define HAVE_F_SETLKW64 1 231#else 232# define HAVE_F_SETLKW64 0 233#endif 234 235#if defined(F_GETLK64) && F_GETLK64+0 != F_GETLK 236# define HAVE_F_GETLK64 1 237#else 238# define HAVE_F_GETLK64 0 239#endif 240 241#if defined(X32) || defined(F_FREESP64) || \ 242 HAVE_F_SETLK64 || HAVE_F_SETLKW64 || HAVE_F_GETLK64 243 244#ifndef HAVE_STRUCT_FLOCK64 245struct flock64 { 246 short int l_type, l_whence; 247 int64_t l_start, l_len; 248 int l_pid; 249}; 250#endif 251 252/* fcntl/lockf */ 253static void 254printflock64(struct tcb *tcp, long addr, int getlk) 255{ 256 struct flock64 fl; 257 258 if (umove(tcp, addr, &fl) < 0) { 259 tprints("{...}"); 260 return; 261 } 262 tprints("{type="); 263 printxval(lockfcmds, fl.l_type, "F_???"); 264 tprints(", whence="); 265 printxval(whence_codes, fl.l_whence, "SEEK_???"); 266 tprintf(", start=%lld, len=%lld", (long long) fl.l_start, (long long) fl.l_len); 267 if (getlk) 268 tprintf(", pid=%lu}", (unsigned long) fl.l_pid); 269 else 270 tprints("}"); 271} 272#endif 273 274/* fcntl/lockf */ 275static void 276printflock(struct tcb *tcp, long addr, int getlk) 277{ 278 struct flock fl; 279 280#if SUPPORTED_PERSONALITIES > 1 281# ifdef X32 282 if (current_personality == 0) { 283 printflock64(tcp, addr, getlk); 284 return; 285 } 286# endif 287 if (current_wordsize != sizeof(fl.l_start)) { 288 if (current_wordsize == 4) { 289 /* 32-bit x86 app on x86_64 and similar cases */ 290 struct { 291 short int l_type; 292 short int l_whence; 293 int32_t l_start; /* off_t */ 294 int32_t l_len; /* off_t */ 295 int32_t l_pid; /* pid_t */ 296 } fl32; 297 if (umove(tcp, addr, &fl32) < 0) { 298 tprints("{...}"); 299 return; 300 } 301 fl.l_type = fl32.l_type; 302 fl.l_whence = fl32.l_whence; 303 fl.l_start = fl32.l_start; 304 fl.l_len = fl32.l_len; 305 fl.l_pid = fl32.l_pid; 306 } else { 307 /* let people know we have a problem here */ 308 tprintf("<decode error: unsupported wordsize %d>", 309 current_wordsize); 310 return; 311 } 312 } else 313#endif 314 { 315 if (umove(tcp, addr, &fl) < 0) { 316 tprints("{...}"); 317 return; 318 } 319 } 320 tprints("{type="); 321 printxval(lockfcmds, fl.l_type, "F_???"); 322 tprints(", whence="); 323 printxval(whence_codes, fl.l_whence, "SEEK_???"); 324#ifdef X32 325 tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len); 326#else 327 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len); 328#endif 329 if (getlk) 330 tprintf(", pid=%lu}", (unsigned long) fl.l_pid); 331 else 332 tprints("}"); 333} 334 335int 336sys_fcntl(struct tcb *tcp) 337{ 338 if (entering(tcp)) { 339 printfd(tcp, tcp->u_arg[0]); 340 tprints(", "); 341 printxval(fcntlcmds, tcp->u_arg[1], "F_???"); 342 switch (tcp->u_arg[1]) { 343 case F_SETFD: 344 tprints(", "); 345 printflags(fdflags, tcp->u_arg[2], "FD_???"); 346 break; 347 case F_SETOWN: case F_DUPFD: 348#ifdef F_DUPFD_CLOEXEC 349 case F_DUPFD_CLOEXEC: 350#endif 351 tprintf(", %ld", tcp->u_arg[2]); 352 break; 353 case F_SETFL: 354 tprints(", "); 355 tprint_open_modes(tcp->u_arg[2]); 356 break; 357 case F_SETLK: case F_SETLKW: 358#ifdef F_FREESP 359 case F_FREESP: 360#endif 361 tprints(", "); 362 printflock(tcp, tcp->u_arg[2], 0); 363 break; 364#if defined(F_FREESP64) || HAVE_F_SETLK64 || HAVE_F_SETLKW64 365#ifdef F_FREESP64 366 case F_FREESP64: 367#endif 368 /* Linux glibc defines SETLK64 as SETLK, 369 even though the kernel has different values - as does Solaris. */ 370#if HAVE_F_SETLK64 371 case F_SETLK64: 372#endif 373#if HAVE_F_SETLKW64 374 case F_SETLKW64: 375#endif 376 tprints(", "); 377 printflock64(tcp, tcp->u_arg[2], 0); 378 break; 379#endif /* defined(F_FREESP64) || HAVE_F_SETLK64 || HAVE_F_SETLKW64 */ 380#ifdef F_NOTIFY 381 case F_NOTIFY: 382 tprints(", "); 383 printflags(notifyflags, tcp->u_arg[2], "DN_???"); 384 break; 385#endif 386#ifdef F_SETLEASE 387 case F_SETLEASE: 388 tprints(", "); 389 printxval(lockfcmds, tcp->u_arg[2], "F_???"); 390 break; 391#endif 392 } 393 } 394 else { 395 switch (tcp->u_arg[1]) { 396 case F_DUPFD: 397#ifdef F_DUPFD_CLOEXEC 398 case F_DUPFD_CLOEXEC: 399#endif 400 case F_SETFD: case F_SETFL: 401 case F_SETLK: case F_SETLKW: 402 case F_SETOWN: case F_GETOWN: 403#ifdef F_NOTIFY 404 case F_NOTIFY: 405#endif 406#ifdef F_SETLEASE 407 case F_SETLEASE: 408#endif 409 break; 410 case F_GETFD: 411 if (syserror(tcp) || tcp->u_rval == 0) 412 return 0; 413 tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval); 414 return RVAL_HEX|RVAL_STR; 415 case F_GETFL: 416 if (syserror(tcp)) 417 return 0; 418 tcp->auxstr = sprint_open_modes(tcp->u_rval); 419 return RVAL_HEX|RVAL_STR; 420 case F_GETLK: 421 tprints(", "); 422 printflock(tcp, tcp->u_arg[2], 1); 423 break; 424#if HAVE_F_GETLK64 425 case F_GETLK64: 426 tprints(", "); 427 printflock64(tcp, tcp->u_arg[2], 1); 428 break; 429#endif 430#ifdef F_GETLEASE 431 case F_GETLEASE: 432 if (syserror(tcp)) 433 return 0; 434 tcp->auxstr = xlookup(lockfcmds, tcp->u_rval); 435 return RVAL_HEX|RVAL_STR; 436#endif 437 default: 438 tprintf(", %#lx", tcp->u_arg[2]); 439 break; 440 } 441 } 442 return 0; 443} 444 445#ifdef LOCK_SH 446 447int 448sys_flock(struct tcb *tcp) 449{ 450 if (entering(tcp)) { 451 printfd(tcp, tcp->u_arg[0]); 452 tprints(", "); 453 printflags(flockcmds, tcp->u_arg[1], "LOCK_???"); 454 } 455 return 0; 456} 457#endif /* LOCK_SH */ 458 459int 460sys_close(struct tcb *tcp) 461{ 462 if (entering(tcp)) { 463 printfd(tcp, tcp->u_arg[0]); 464 } 465 return 0; 466} 467 468static int 469do_dup2(struct tcb *tcp, int flags_arg) 470{ 471 if (entering(tcp)) { 472 printfd(tcp, tcp->u_arg[0]); 473 tprints(", "); 474 printfd(tcp, tcp->u_arg[1]); 475 if (flags_arg >= 0) { 476 tprints(", "); 477 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???"); 478 } 479 } 480 return 0; 481} 482 483int 484sys_dup2(struct tcb *tcp) 485{ 486 return do_dup2(tcp, -1); 487} 488 489int 490sys_dup3(struct tcb *tcp) 491{ 492 return do_dup2(tcp, 2); 493} 494 495#if defined(ALPHA) 496int 497sys_getdtablesize(struct tcb *tcp) 498{ 499 return 0; 500} 501#endif 502 503static int 504decode_select(struct tcb *tcp, long *args, enum bitness_t bitness) 505{ 506 int i, j; 507 int nfds, fdsize; 508 fd_set *fds; 509 const char *sep; 510 long arg; 511 512 /* Kernel truncates arg[0] to int, we do the same. */ 513 nfds = (int) args[0]; 514 515 /* Kernel rejects negative nfds, so we don't parse it either. */ 516 if (nfds < 0) { 517 nfds = 0; 518 fds = NULL; 519 } 520 /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */ 521 if (nfds > 1024*1024) 522 nfds = 1024*1024; 523 524 /* 525 * We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below. 526 * Instead of args[0], use nfds for fd count, fdsize for array lengths. 527 */ 528 fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize; 529 530 if (entering(tcp)) { 531 tprintf("%d", (int) args[0]); 532 533 if (fdsize > 0) { 534 fds = malloc(fdsize); 535 if (!fds) 536 die_out_of_memory(); 537 } 538 for (i = 0; i < 3; i++) { 539 arg = args[i+1]; 540 if (arg == 0) { 541 tprints(", NULL"); 542 continue; 543 } 544 if (!verbose(tcp) || !fds) { 545 tprintf(", %#lx", arg); 546 continue; 547 } 548 if (umoven(tcp, arg, fdsize, (char *) fds) < 0) { 549 tprints(", [?]"); 550 continue; 551 } 552 tprints(", ["); 553 for (j = 0, sep = "";; j++) { 554 j = next_set_bit(fds, j, nfds); 555 if (j < 0) 556 break; 557 tprints(sep); 558 printfd(tcp, j); 559 sep = " "; 560 } 561 tprints("]"); 562 } 563 free(fds); 564 tprints(", "); 565 printtv_bitness(tcp, args[4], bitness, 0); 566 } 567 else { 568 static char outstr[1024]; 569 char *outptr; 570#define end_outstr (outstr + sizeof(outstr)) 571 int ready_fds; 572 573 if (syserror(tcp)) 574 return 0; 575 576 ready_fds = tcp->u_rval; 577 if (ready_fds == 0) { 578 tcp->auxstr = "Timeout"; 579 return RVAL_STR; 580 } 581 582 fds = malloc(fdsize); 583 if (!fds) 584 die_out_of_memory(); 585 586 outptr = outstr; 587 sep = ""; 588 for (i = 0; i < 3 && ready_fds > 0; i++) { 589 int first = 1; 590 591 arg = args[i+1]; 592 if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0) 593 continue; 594 for (j = 0;; j++) { 595 j = next_set_bit(fds, j, nfds); 596 if (j < 0) 597 break; 598 /* +2 chars needed at the end: ']',NUL */ 599 if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) { 600 if (first) { 601 outptr += sprintf(outptr, "%s%s [%u", 602 sep, 603 i == 0 ? "in" : i == 1 ? "out" : "except", 604 j 605 ); 606 first = 0; 607 sep = ", "; 608 } 609 else { 610 outptr += sprintf(outptr, " %u", j); 611 } 612 } 613 if (--ready_fds == 0) 614 break; 615 } 616 if (outptr != outstr) 617 *outptr++ = ']'; 618 } 619 free(fds); 620 /* This contains no useful information on SunOS. */ 621 if (args[4]) { 622 if (outptr < end_outstr - (10 + TIMEVAL_TEXT_BUFSIZE)) { 623 outptr += sprintf(outptr, "%sleft ", sep); 624 outptr = sprinttv(outptr, tcp, args[4], bitness, /*special:*/ 0); 625 } 626 } 627 *outptr = '\0'; 628 tcp->auxstr = outstr; 629 return RVAL_STR; 630#undef end_outstr 631 } 632 return 0; 633} 634 635int 636sys_oldselect(struct tcb *tcp) 637{ 638 long args[5]; 639 640 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) { 641 tprints("[...]"); 642 return 0; 643 } 644 return decode_select(tcp, args, BITNESS_CURRENT); 645} 646 647#ifdef ALPHA 648int 649sys_osf_select(struct tcb *tcp) 650{ 651 long *args = tcp->u_arg; 652 return decode_select(tcp, args, BITNESS_32); 653} 654#endif 655 656static const struct xlat epollctls[] = { 657#ifdef EPOLL_CTL_ADD 658 XLAT(EPOLL_CTL_ADD), 659#endif 660#ifdef EPOLL_CTL_MOD 661 XLAT(EPOLL_CTL_MOD), 662#endif 663#ifdef EPOLL_CTL_DEL 664 XLAT(EPOLL_CTL_DEL), 665#endif 666 XLAT_END 667}; 668 669static const struct xlat epollevents[] = { 670#ifdef EPOLLIN 671 XLAT(EPOLLIN), 672#endif 673#ifdef EPOLLPRI 674 XLAT(EPOLLPRI), 675#endif 676#ifdef EPOLLOUT 677 XLAT(EPOLLOUT), 678#endif 679#ifdef EPOLLRDNORM 680 XLAT(EPOLLRDNORM), 681#endif 682#ifdef EPOLLRDBAND 683 XLAT(EPOLLRDBAND), 684#endif 685#ifdef EPOLLWRNORM 686 XLAT(EPOLLWRNORM), 687#endif 688#ifdef EPOLLWRBAND 689 XLAT(EPOLLWRBAND), 690#endif 691#ifdef EPOLLMSG 692 XLAT(EPOLLMSG), 693#endif 694#ifdef EPOLLERR 695 XLAT(EPOLLERR), 696#endif 697#ifdef EPOLLHUP 698 XLAT(EPOLLHUP), 699#endif 700#ifdef EPOLLRDHUP 701 XLAT(EPOLLRDHUP), 702#endif 703#ifdef EPOLLONESHOT 704 XLAT(EPOLLONESHOT), 705#endif 706#ifdef EPOLLET 707 XLAT(EPOLLET), 708#endif 709 XLAT_END 710}; 711 712/* Not aliased to printargs_ld: we want it to have a distinct address */ 713int 714sys_epoll_create(struct tcb *tcp) 715{ 716 return printargs_ld(tcp); 717} 718 719static const struct xlat epollflags[] = { 720#ifdef EPOLL_CLOEXEC 721 XLAT(EPOLL_CLOEXEC), 722#endif 723#ifdef EPOLL_NONBLOCK 724 XLAT(EPOLL_NONBLOCK), 725#endif 726 XLAT_END 727}; 728 729int 730sys_epoll_create1(struct tcb *tcp) 731{ 732 if (entering(tcp)) 733 printflags(epollflags, tcp->u_arg[0], "EPOLL_???"); 734 return 0; 735} 736 737#ifdef HAVE_SYS_EPOLL_H 738static void 739print_epoll_event(struct epoll_event *ev) 740{ 741 tprints("{"); 742 printflags(epollevents, ev->events, "EPOLL???"); 743 /* We cannot know what format the program uses, so print u32 and u64 744 which will cover every value. */ 745 tprintf(", {u32=%" PRIu32 ", u64=%" PRIu64 "}}", 746 ev->data.u32, ev->data.u64); 747} 748#endif 749 750int 751sys_epoll_ctl(struct tcb *tcp) 752{ 753 if (entering(tcp)) { 754 printfd(tcp, tcp->u_arg[0]); 755 tprints(", "); 756 printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???"); 757 tprints(", "); 758 printfd(tcp, tcp->u_arg[2]); 759 tprints(", "); 760 if (tcp->u_arg[3] == 0) 761 tprints("NULL"); 762 else { 763#ifdef HAVE_SYS_EPOLL_H 764 struct epoll_event ev; 765 if (umove(tcp, tcp->u_arg[3], &ev) == 0) 766 print_epoll_event(&ev); 767 else 768#endif 769 tprints("{...}"); 770 } 771 } 772 return 0; 773} 774 775static void 776epoll_wait_common(struct tcb *tcp) 777{ 778 if (entering(tcp)) { 779 printfd(tcp, tcp->u_arg[0]); 780 tprints(", "); 781 } else { 782 if (syserror(tcp)) 783 tprintf("%lx", tcp->u_arg[1]); 784 else if (tcp->u_rval == 0) 785 tprints("{}"); 786 else { 787#ifdef HAVE_SYS_EPOLL_H 788 struct epoll_event ev, *start, *cur, *end; 789 int failed = 0; 790 791 tprints("{"); 792 start = (struct epoll_event *) tcp->u_arg[1]; 793 end = start + tcp->u_rval; 794 for (cur = start; cur < end; ++cur) { 795 if (cur > start) 796 tprints(", "); 797 if (umove(tcp, (long) cur, &ev) == 0) 798 print_epoll_event(&ev); 799 else { 800 tprints("?"); 801 failed = 1; 802 break; 803 } 804 } 805 tprints("}"); 806 if (failed) 807 tprintf(" %#lx", (long) start); 808#else 809 tprints("{...}"); 810#endif 811 } 812 tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]); 813 } 814} 815 816int 817sys_epoll_wait(struct tcb *tcp) 818{ 819 epoll_wait_common(tcp); 820 return 0; 821} 822 823int 824sys_epoll_pwait(struct tcb *tcp) 825{ 826 epoll_wait_common(tcp); 827 if (exiting(tcp)) { 828 tprints(", "); 829 /* NB: kernel requires arg[5] == NSIG / 8 */ 830 print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]); 831 tprintf(", %lu", tcp->u_arg[5]); 832 } 833 return 0; 834} 835 836int 837sys_select(struct tcb *tcp) 838{ 839 return decode_select(tcp, tcp->u_arg, BITNESS_CURRENT); 840} 841 842int 843sys_pselect6(struct tcb *tcp) 844{ 845 int rc = decode_select(tcp, tcp->u_arg, BITNESS_CURRENT); 846 if (entering(tcp)) { 847 long r; 848 struct { 849 unsigned long ptr; 850 unsigned long len; 851 } data; 852#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 853 if (current_wordsize == 4) { 854 struct { 855 uint32_t ptr; 856 uint32_t len; 857 } data32; 858 r = umove(tcp, tcp->u_arg[5], &data32); 859 data.ptr = data32.ptr; 860 data.len = data32.len; 861 } else 862#endif 863 r = umove(tcp, tcp->u_arg[5], &data); 864 if (r < 0) 865 tprintf(", %#lx", tcp->u_arg[5]); 866 else { 867 tprints(", {"); 868 /* NB: kernel requires data.len == NSIG / 8 */ 869 print_sigset_addr_len(tcp, data.ptr, data.len); 870 tprintf(", %lu}", data.len); 871 } 872 } 873 return rc; 874} 875 876static int 877do_eventfd(struct tcb *tcp, int flags_arg) 878{ 879 if (entering(tcp)) { 880 tprintf("%lu", tcp->u_arg[0]); 881 if (flags_arg >= 0) { 882 tprints(", "); 883 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???"); 884 } 885 } 886 return 0; 887} 888 889int 890sys_eventfd(struct tcb *tcp) 891{ 892 return do_eventfd(tcp, -1); 893} 894 895int 896sys_eventfd2(struct tcb *tcp) 897{ 898 return do_eventfd(tcp, 1); 899} 900 901int 902sys_perf_event_open(struct tcb *tcp) 903{ 904 if (entering(tcp)) { 905 tprintf("%#lx, %d, %d, %d, ", 906 tcp->u_arg[0], 907 (int) tcp->u_arg[1], 908 (int) tcp->u_arg[2], 909 (int) tcp->u_arg[3]); 910 printflags(perf_event_open_flags, tcp->u_arg[4], 911 "PERF_FLAG_???"); 912 } 913 return 0; 914} 915