1/* 2 * Copyright (c) 2004-2007 Ulrich Drepper <drepper@redhat.com> 3 * Copyright (c) 2004 Roland McGrath <roland@redhat.com> 4 * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org> 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#ifdef HAVE_SYS_EPOLL_H 33# include <sys/epoll.h> 34#endif 35 36SYS_FUNC(epoll_create) 37{ 38 tprintf("%d", (int) tcp->u_arg[0]); 39 40 return RVAL_DECODED | RVAL_FD; 41} 42 43#include "xlat/epollflags.h" 44 45SYS_FUNC(epoll_create1) 46{ 47 printflags(epollflags, tcp->u_arg[0], "EPOLL_???"); 48 49 return RVAL_DECODED | RVAL_FD; 50} 51 52#ifdef HAVE_SYS_EPOLL_H 53# include "xlat/epollevents.h" 54 55static void 56print_epoll_event(struct epoll_event *ev) 57{ 58 tprints("{"); 59 printflags(epollevents, ev->events, "EPOLL???"); 60 /* We cannot know what format the program uses, so print u32 and u64 61 which will cover every value. */ 62 tprintf(", {u32=%" PRIu32 ", u64=%" PRIu64 "}}", 63 ev->data.u32, ev->data.u64); 64} 65#endif 66 67#include "xlat/epollctls.h" 68 69SYS_FUNC(epoll_ctl) 70{ 71 struct epoll_event ev; 72 73 printfd(tcp, tcp->u_arg[0]); 74 tprints(", "); 75 printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???"); 76 tprints(", "); 77 printfd(tcp, tcp->u_arg[2]); 78 tprints(", "); 79#ifdef HAVE_SYS_EPOLL_H 80 if (EPOLL_CTL_DEL == tcp->u_arg[1]) 81 printaddr(tcp->u_arg[3]); 82 else if (!umove_or_printaddr(tcp, tcp->u_arg[3], &ev)) 83 print_epoll_event(&ev); 84#else 85 printaddr(tcp->u_arg[3]); 86#endif 87 88 return RVAL_DECODED; 89} 90 91static void 92print_epoll_event_array(struct tcb *tcp, const long addr, const long len) 93{ 94#ifdef HAVE_SYS_EPOLL_H 95 struct epoll_event ev, *start, *cur, *end; 96 97 if (!len) { 98 tprints("[]"); 99 return; 100 } 101 102 if (umove_or_printaddr(tcp, addr, &ev)) 103 return; 104 105 tprints("["); 106 print_epoll_event(&ev); 107 108 start = (struct epoll_event *) addr; 109 end = start + len; 110 for (cur = start + 1; cur < end; ++cur) { 111 tprints(", "); 112 if (umove_or_printaddr(tcp, (long) cur, &ev)) 113 break; 114 print_epoll_event(&ev); 115 } 116 tprints("]"); 117#else 118 printaddr(addr); 119#endif 120} 121 122static void 123epoll_wait_common(struct tcb *tcp) 124{ 125 if (entering(tcp)) { 126 printfd(tcp, tcp->u_arg[0]); 127 tprints(", "); 128 } else { 129 print_epoll_event_array(tcp, tcp->u_arg[1], tcp->u_rval); 130 tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]); 131 } 132} 133 134SYS_FUNC(epoll_wait) 135{ 136 epoll_wait_common(tcp); 137 return 0; 138} 139 140SYS_FUNC(epoll_pwait) 141{ 142 epoll_wait_common(tcp); 143 if (exiting(tcp)) { 144 tprints(", "); 145 /* NB: kernel requires arg[5] == NSIG / 8 */ 146 print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]); 147 tprintf(", %lu", tcp->u_arg[5]); 148 } 149 return 0; 150} 151