2009-02-13 13:26:31 +03:00
/* This test is not yet added to Makefile */
2009-02-25 17:24:02 +03:00
# include <stdlib.h>
2009-02-13 13:26:31 +03:00
# include <stddef.h>
# include <unistd.h>
# include <signal.h>
# include <sys/types.h>
# include <sys/socket.h>
2009-02-25 17:24:02 +03:00
2009-02-13 13:26:31 +03:00
static const struct sockaddr sa ;
2009-02-25 17:24:02 +03:00
int main ( int argc , char * argv [ ] )
2009-02-13 13:26:31 +03:00
{
int loops ;
int pid ;
sigset_t set ;
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 17:24:02 +03:00
if ( pid < 0 )
exit ( 1 ) ;
2009-02-13 13:26:31 +03:00
if ( ! pid ) {
/* child */
int child = getpid ( ) ;
loops = 99 ;
while ( - - loops ) {
pid = fork ( ) ;
2009-02-25 17:24:02 +03:00
if ( pid < 0 )
exit ( 1 ) ;
2009-02-13 13:26:31 +03:00
if ( ! pid ) {
/* grandchild: kill child */
kill ( child , SIGKILL ) ;
2009-02-25 17:24:02 +03:00
exit ( 0 ) ;
2009-02-13 13:26:31 +03:00
}
2009-02-25 17:24:02 +03:00
2009-02-13 13:26:31 +03: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 17:24:02 +03:00
case 0 :
break ; /* intentional empty */
case 1 :
sendto ( - 1 , " Hello cruel world " , 17 , 0 , & sa , sizeof ( sa ) ) ;
break ;
2009-02-13 13:26:31 +03:00
}
2009-02-25 17:24:02 +03:00
2009-02-13 13:26:31 +03:00
/* kill grandchild */
kill ( pid , SIGKILL ) ;
}
2009-02-25 17:24:02 +03:00
exit ( 0 ) ;
2009-02-13 13:26:31 +03:00
}
2009-02-25 17:24:02 +03:00
2009-02-13 13:26:31 +03:00
/* parent */
wait ( NULL ) ;
}
2009-02-25 17:24:02 +03:00
2009-02-13 13:26:31 +03:00
return 0 ;
}