static void client_handler( void* _client, int events ) { Client client = _client; if (events & SYS_EVENT_READ) { int ret; /* read into buffer, one character at a time */ ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 ); if (ret != 1) { fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n", client, ret, strerror(errno) ); goto ExitClient; } if (client->in_buff[client->in_pos] == '\r' || client->in_buff[client->in_pos] == '\n' ) { const char* cmd = client->in_buff; client->in_buff[client->in_pos] = 0; if (client->in_pos > 0) { client_handle_line( client, cmd ); client->in_pos = 0; } } else client->in_pos += 1; } if (events & SYS_EVENT_WRITE) { int ret; /* write from output buffer, one char at a time */ ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 ); if (ret != 1) { fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n", client, ret, strerror(errno) ); goto ExitClient; } client->out_pos += 1; if (client->out_pos == client->out_size) { client->out_size = 0; client->out_pos = 0; /* we don't need to write */ sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client ); } } return; ExitClient: printf( "client %p exiting\n", client ); client_free( client ); }
static void remote_call_event( void* opaque, int events ) { RemoteCall call = opaque; S("%s: called for call (%d,%d), events=%02x\n", __FUNCTION__, call->from_port, call->to_port, events); if (events & SYS_EVENT_READ) { /* simply drain the channel */ char temp[32]; int n = sys_channel_read( call->channel, temp, sizeof(temp) ); if (n <= 0) { /* remote emulator probably quitted */ //S("%s: emulator %d quitted with %d: %s\n", __FUNCTION__, call->to_port, errno, errno_str); remote_call_free( call ); return; } } if (events & SYS_EVENT_WRITE) { int n; if (S_ACTIVE) { int nn; S("%s: call (%d,%d) sending %d bytes '", __FUNCTION__, call->from_port, call->to_port, call->buff_len - call->buff_pos ); for (nn = call->buff_pos; nn < call->buff_len; nn++) { int c = call->buff[nn]; if (c < 32) { if (c == '\n') S("\\n"); else if (c == '\t') S("\\t"); else if (c == '\r') S("\\r"); else S("\\x%02x", c); } else S("%c", c); } S("'\n"); } n = sys_channel_write( call->channel, call->buff + call->buff_pos, call->buff_len - call->buff_pos ); if (n <= 0) { /* remote emulator probably quitted */ S("%s: emulator %d quitted unexpectedly with error %d: %s\n", __FUNCTION__, call->to_port, errno, errno_str); if (call->result_func) call->result_func( call->result_opaque, 0 ); remote_call_free( call ); return; } call->buff_pos += n; if (call->buff_pos >= call->buff_len) { /* cool, we sent everything */ S("%s: finished sending data to %d\n", __FUNCTION__, call->to_port); if (!call->quitting) { call->quitting = 1; sprintf( call->buff, "quit\n" ); call->buff_len = strlen(call->buff); call->buff_pos = 0; } else { call->quitting = 0; if (call->result_func) call->result_func( call->result_opaque, 1 ); sys_channel_on( call->channel, SYS_EVENT_READ, remote_call_event, call ); } } } }