2009-02-25 14:24:02 +00:00
# include <stdlib.h>
2009-02-13 10:26:31 +00:00
# include <stddef.h>
# include <unistd.h>
# include <signal.h>
# include <sys/types.h>
# include <sys/socket.h>
2011-06-08 14:08:59 +02:00
# include <stdio.h>
2013-05-02 15:43:45 -04:00
# include <sys/wait.h>
2009-02-25 14:24:02 +00:00
2009-02-13 10:26:31 +00:00
static const struct sockaddr sa ;
2009-02-25 14:24:02 +00:00
int main ( int argc , char * argv [ ] )
2009-02-13 10:26:31 +00:00
{
int loops ;
int pid ;
sigset_t set ;
2011-06-08 14:08:59 +02:00
printf (
" Please run me under 'strace -f -oLOG', and examine LOG file for incorrect \n "
" decoding of interrupted syscalls: grep for 'sendto', '?? " /* anti-trigraph gap */ " ?', 'unavailable'. \n "
" Pass number of iterations in argv[1] (default: 999). \n "
) ;
2011-06-08 16:07:03 +02:00
fflush ( NULL ) ;
2011-06-08 14:08:59 +02:00
2009-02-13 10:26:31 +00:00
sigemptyset ( & set ) ;
sigaddset ( & set , SIGCHLD ) ;
sigprocmask ( SIG_BLOCK , & set , NULL ) ;
loops = 999 ;
if ( argv [ 1 ] )
loops = atoi ( argv [ 1 ] ) ;
while ( - - loops > = 0 ) {
pid = fork ( ) ;
2009-02-25 14:24:02 +00:00
if ( pid < 0 )
exit ( 1 ) ;
2009-02-13 10:26:31 +00:00
if ( ! pid ) {
/* child */
int child = getpid ( ) ;
loops = 99 ;
while ( - - loops ) {
pid = fork ( ) ;
2009-02-25 14:24:02 +00:00
if ( pid < 0 )
exit ( 1 ) ;
2009-02-13 10:26:31 +00:00
if ( ! pid ) {
/* grandchild: kill child */
kill ( child , SIGKILL ) ;
2009-02-25 14:24:02 +00:00
exit ( 0 ) ;
2009-02-13 10:26:31 +00:00
}
2009-02-25 14:24:02 +00:00
2009-02-13 10:26:31 +00:00
/* Add various syscalls you want to test here.
* strace will decode them and suddenly find
* process disappearing .
* But leave at least one case " empty " , so that
* " kill grandchild " happens quicker .
* This produces cases when strace can ' t even
* decode syscall number before process dies .
*/
switch ( loops & 1 ) {
2009-02-25 14:24:02 +00:00
case 0 :
2011-06-08 14:08:59 +02:00
break ; /* intentionally empty */
2009-02-25 14:24:02 +00:00
case 1 :
sendto ( - 1 , " Hello cruel world " , 17 , 0 , & sa , sizeof ( sa ) ) ;
break ;
2009-02-13 10:26:31 +00:00
}
2009-02-25 14:24:02 +00:00
2009-02-13 10:26:31 +00:00
/* kill grandchild */
kill ( pid , SIGKILL ) ;
}
2009-02-25 14:24:02 +00:00
exit ( 0 ) ;
2009-02-13 10:26:31 +00:00
}
2009-02-25 14:24:02 +00:00
2009-02-13 10:26:31 +00:00
/* parent */
wait ( NULL ) ;
}
2009-02-25 14:24:02 +00:00
2009-02-13 10:26:31 +00:00
return 0 ;
}