2015-07-30 19:49:42 +03:00
/*
* Copyright ( c ) 1993 , 1994 , 1995 , 1996 Rick Sladkey < jrs @ world . std . com >
* Copyright ( c ) 1996 - 1999 Wichert Akkerman < wichert @ cistron . nl >
2017-05-22 20:14:52 +03:00
* Copyright ( c ) 1999 - 2017 The strace developers .
2015-07-30 19:49:42 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
# include <poll.h>
2018-01-06 04:45:16 +03:00
# include "xstring.h"
2015-07-30 19:49:42 +03:00
# include "xlat/pollflags.h"
2016-05-08 02:09:09 +03:00
static bool
print_pollfd ( struct tcb * tcp , void * elem_buf , size_t elem_size , void * data )
2015-07-30 22:46:11 +03:00
{
2016-05-08 02:09:09 +03:00
const struct pollfd * fds = elem_buf ;
2015-07-30 22:46:11 +03:00
tprints ( " {fd= " ) ;
printfd ( tcp , fds - > fd ) ;
if ( fds - > fd > = 0 ) {
tprints ( " , events= " ) ;
2016-05-17 01:03:51 +03:00
printflags ( pollflags , ( unsigned short ) fds - > events , " POLL??? " ) ;
2015-07-30 22:46:11 +03:00
}
tprints ( " } " ) ;
2016-05-08 02:09:09 +03:00
return true ;
2015-07-30 22:46:11 +03:00
}
2016-05-08 02:09:09 +03:00
static void
2015-07-30 22:46:11 +03:00
decode_poll_entering ( struct tcb * tcp )
2015-07-30 19:49:42 +03:00
{
2016-12-26 13:26:03 +03:00
const kernel_ulong_t addr = tcp - > u_arg [ 0 ] ;
2015-07-30 22:46:11 +03:00
const unsigned int nfds = tcp - > u_arg [ 1 ] ;
2016-05-08 02:09:09 +03:00
struct pollfd fds ;
2015-07-30 22:46:11 +03:00
2016-05-08 02:09:09 +03:00
print_array ( tcp , addr , nfds , & fds , sizeof ( fds ) ,
umoven_or_printaddr , print_pollfd , 0 ) ;
tprintf ( " , %u, " , nfds ) ;
2015-07-30 22:46:11 +03:00
}
static int
2016-12-26 13:26:03 +03:00
decode_poll_exiting ( struct tcb * const tcp , const kernel_ulong_t pts )
2015-07-30 22:46:11 +03:00
{
struct pollfd fds ;
const unsigned int nfds = tcp - > u_arg [ 1 ] ;
const unsigned long size = sizeof ( fds ) * nfds ;
2016-12-26 13:26:03 +03:00
const kernel_ulong_t start = tcp - > u_arg [ 0 ] ;
const kernel_ulong_t end = start + size ;
kernel_ulong_t cur ;
2016-12-22 20:59:19 +03:00
const unsigned int max_printed =
2016-12-18 17:09:51 +03:00
abbrev ( tcp ) ? max_strlen : - 1U ;
2016-12-22 20:59:19 +03:00
unsigned int printed ;
2015-07-30 22:46:11 +03:00
static char outstr [ 1024 ] ;
char * outptr ;
2015-07-30 19:49:42 +03:00
# define end_outstr (outstr + sizeof(outstr))
2015-07-30 22:46:11 +03:00
if ( syserror ( tcp ) )
return 0 ;
if ( tcp - > u_rval = = 0 ) {
tcp - > auxstr = " Timeout " ;
return RVAL_STR ;
}
2015-07-30 19:49:42 +03:00
2015-07-30 22:46:11 +03:00
if ( ! verbose ( tcp ) | | ! start | | ! nfds | |
size / sizeof ( fds ) ! = nfds | | end < start )
return 0 ;
2015-07-30 19:49:42 +03:00
2015-07-30 22:46:11 +03:00
outptr = outstr ;
2016-02-16 03:44:16 +03:00
for ( printed = 0 , cur = start ; cur < end ; cur + = sizeof ( fds ) ) {
2015-07-30 22:46:11 +03:00
if ( umove ( tcp , cur , & fds ) < 0 ) {
if ( outptr = = outstr )
2015-07-30 19:49:42 +03:00
* outptr + + = ' [ ' ;
2015-07-30 22:46:11 +03:00
else
outptr = stpcpy ( outptr , " , " ) ;
2018-01-06 04:45:16 +03:00
outptr + = xsnprintf ( outptr ,
sizeof ( outstr ) - ( outptr - outstr ) ,
" %# " PRI_klx , cur ) ;
2015-07-30 22:46:11 +03:00
break ;
2015-07-30 19:49:42 +03:00
}
2015-07-30 22:46:11 +03:00
if ( ! fds . revents )
continue ;
if ( outptr = = outstr )
* outptr + + = ' [ ' ;
else
outptr = stpcpy ( outptr , " , " ) ;
2016-02-16 03:44:16 +03:00
if ( printed > = max_printed ) {
2015-07-30 22:46:11 +03:00
outptr = stpcpy ( outptr , " ... " ) ;
break ;
2015-07-30 19:49:42 +03:00
}
2015-07-30 22:46:11 +03:00
static const char fmt [ ] = " {fd=%d, revents= " ;
char fdstr [ sizeof ( fmt ) + sizeof ( int ) * 3 ] ;
2018-01-06 04:45:16 +03:00
xsprintf ( fdstr , fmt , fds . fd ) ;
2015-07-30 19:49:42 +03:00
2016-05-15 17:23:06 +03:00
const char * flagstr = sprintflags ( " " , pollflags ,
( unsigned short ) fds . revents ) ;
2015-07-30 22:46:11 +03:00
2016-02-16 03:04:37 +03:00
if ( outptr + strlen ( fdstr ) + strlen ( flagstr ) + 1 > =
end_outstr - ( 2 + 2 * sizeof ( long ) + sizeof ( " , ], ... " ) ) ) {
2015-07-30 22:46:11 +03:00
outptr = stpcpy ( outptr , " ... " ) ;
break ;
}
outptr = stpcpy ( outptr , fdstr ) ;
outptr = stpcpy ( outptr , flagstr ) ;
* outptr + + = ' } ' ;
2016-02-16 03:44:16 +03:00
+ + printed ;
2015-07-30 22:46:11 +03:00
}
if ( outptr ! = outstr )
* outptr + + = ' ] ' ;
* outptr = ' \0 ' ;
if ( pts ) {
2015-09-18 20:44:16 +03:00
const char * str = sprint_timespec ( tcp , pts ) ;
2015-07-30 22:46:11 +03:00
2015-09-18 20:44:16 +03:00
if ( outptr + sizeof ( " , left " ) + strlen ( str ) < end_outstr ) {
2015-07-30 22:46:11 +03:00
outptr = stpcpy ( outptr , outptr = = outstr ? " left " : " , left " ) ;
2015-09-18 20:44:16 +03:00
outptr = stpcpy ( outptr , str ) ;
2015-07-30 22:46:11 +03:00
} else {
outptr = stpcpy ( outptr , " , ... " ) ;
}
2015-07-30 19:49:42 +03:00
}
2015-07-30 22:46:11 +03:00
if ( outptr = = outstr )
return 0 ;
tcp - > auxstr = outstr ;
return RVAL_STR ;
# undef end_outstr
2015-07-30 19:49:42 +03:00
}
SYS_FUNC ( poll )
{
if ( entering ( tcp ) ) {
2016-05-08 02:09:09 +03:00
decode_poll_entering ( tcp ) ;
int timeout = tcp - > u_arg [ 2 ] ;
2015-07-30 22:46:11 +03:00
2015-07-30 19:49:42 +03:00
# ifdef INFTIM
2016-05-08 02:09:09 +03:00
if ( INFTIM = = timeout )
2015-07-30 19:49:42 +03:00
tprints ( " INFTIM " ) ;
else
# endif
2016-05-08 02:09:09 +03:00
tprintf ( " %d " , timeout ) ;
2015-07-30 22:46:11 +03:00
2016-05-08 02:09:09 +03:00
return 0 ;
2015-07-30 22:46:11 +03:00
} else {
return decode_poll_exiting ( tcp , 0 ) ;
2015-07-30 19:49:42 +03:00
}
}
SYS_FUNC ( ppoll )
{
if ( entering ( tcp ) ) {
2016-05-08 02:09:09 +03:00
decode_poll_entering ( tcp ) ;
2015-07-30 22:46:11 +03:00
2015-07-30 19:49:42 +03:00
print_timespec ( tcp , tcp - > u_arg [ 2 ] ) ;
tprints ( " , " ) ;
2016-12-28 02:32:44 +03:00
/* NB: kernel requires arg[4] == NSIG_BYTES */
2015-07-30 19:49:42 +03:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 4 ] ) ;
2016-12-26 13:16:35 +03:00
tprintf ( " , % " PRI_klu , tcp - > u_arg [ 4 ] ) ;
2015-07-30 22:46:11 +03:00
2016-05-08 02:09:09 +03:00
return 0 ;
2015-07-30 22:46:11 +03:00
} else {
return decode_poll_exiting ( tcp , tcp - > u_arg [ 2 ] ) ;
2015-07-30 19:49:42 +03:00
}
}