(root)/
strace-6.5/
src/
epoll.c
       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@strace.io>
       5   * Copyright (c) 2015-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: LGPL-2.1-or-later
       9   */
      10  
      11  #include "defs.h"
      12  #include "kernel_fcntl.h"
      13  #include <sys/epoll.h>
      14  
      15  SYS_FUNC(epoll_create)
      16  {
      17  	/* size */
      18  	int size = tcp->u_arg[0];
      19  	PRINT_VAL_D(size);
      20  
      21  	return RVAL_DECODED | RVAL_FD;
      22  }
      23  
      24  #include "xlat/epollflags.h"
      25  
      26  SYS_FUNC(epoll_create1)
      27  {
      28  	/* flags */
      29  	printflags(epollflags, tcp->u_arg[0], "EPOLL_???");
      30  
      31  	return RVAL_DECODED | RVAL_FD;
      32  }
      33  
      34  #include "xlat/epollevents.h"
      35  
      36  static void
      37  print_epoll_data(const epoll_data_t data)
      38  {
      39  	/*
      40  	 * We cannot know what format the tracee uses, so
      41  	 * print both u32 and u66 which will cover every value.
      42  	 */
      43  	tprint_struct_begin();
      44  	PRINT_FIELD_U(data, u32);
      45  	tprint_struct_next();
      46  	PRINT_FIELD_U(data, u64);
      47  	tprint_struct_end();
      48  }
      49  
      50  static bool
      51  print_epoll_event(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
      52  {
      53  	const struct epoll_event *ev = elem_buf;
      54  
      55  	tprint_struct_begin();
      56  	PRINT_FIELD_FLAGS(*ev, events, epollevents, "EPOLL???");
      57  	tprint_struct_next();
      58  	PRINT_FIELD_OBJ_VAL(*ev, data, print_epoll_data);
      59  	tprint_struct_end();
      60  
      61  	return true;
      62  }
      63  
      64  #include "xlat/epollctls.h"
      65  
      66  SYS_FUNC(epoll_ctl)
      67  {
      68  	/* epfd */
      69  	printfd(tcp, tcp->u_arg[0]);
      70  	tprint_arg_next();
      71  
      72  	/* op */
      73  	const unsigned int op = tcp->u_arg[1];
      74  	printxval(epollctls, op, "EPOLL_CTL_???");
      75  	tprint_arg_next();
      76  
      77  	/* fd */
      78  	printfd(tcp, tcp->u_arg[2]);
      79  	tprint_arg_next();
      80  
      81  	/* event */
      82  	struct epoll_event ev;
      83  	if (EPOLL_CTL_DEL == op)
      84  		printaddr(tcp->u_arg[3]);
      85  	else if (!umove_or_printaddr(tcp, tcp->u_arg[3], &ev))
      86  		print_epoll_event(tcp, &ev, sizeof(ev), 0);
      87  
      88  	return RVAL_DECODED;
      89  }
      90  
      91  static void
      92  epoll_wait_common(struct tcb *tcp, const print_obj_by_addr_fn print_timeout)
      93  {
      94  	if (entering(tcp)) {
      95  		/* epfd */
      96  		printfd(tcp, tcp->u_arg[0]);
      97  		tprint_arg_next();
      98  	} else {
      99  		/* events */
     100  		struct epoll_event ev;
     101  		print_array(tcp, tcp->u_arg[1], tcp->u_rval, &ev, sizeof(ev),
     102  			    tfetch_mem, print_epoll_event, 0);
     103  		tprint_arg_next();
     104  
     105  		/* maxevents */
     106  		int maxevents = tcp->u_arg[2];
     107  		PRINT_VAL_D(maxevents);
     108  		tprint_arg_next();
     109  
     110  		/* timeout */
     111  		print_timeout(tcp, tcp->u_arg[3]);
     112  	}
     113  }
     114  
     115  static int
     116  print_timeout_int(struct tcb *tcp, kernel_ulong_t arg)
     117  {
     118  	int timeout = arg;
     119  	PRINT_VAL_D(timeout);
     120  	return 0;
     121  }
     122  
     123  SYS_FUNC(epoll_wait)
     124  {
     125  	epoll_wait_common(tcp, print_timeout_int);
     126  	return 0;
     127  }
     128  
     129  static int
     130  epoll_pwait_common(struct tcb *tcp, const print_obj_by_addr_fn print_timeout)
     131  {
     132  	epoll_wait_common(tcp, print_timeout);
     133  	if (exiting(tcp)) {
     134  		tprint_arg_next();
     135  		/* sigmask */
     136  		/* NB: kernel requires arg[5] == NSIG_BYTES */
     137  		print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]);
     138  		tprint_arg_next();
     139  
     140  		/* sigsetsize */
     141  		PRINT_VAL_U(tcp->u_arg[5]);
     142  	}
     143  	return 0;
     144  }
     145  
     146  SYS_FUNC(epoll_pwait)
     147  {
     148  	return epoll_pwait_common(tcp, print_timeout_int);
     149  }
     150  
     151  SYS_FUNC(epoll_pwait2)
     152  {
     153  	return epoll_pwait_common(tcp, print_timespec64);
     154  }