void handle_event(attrib * attribs, const char *eventname, void *data) { while (attribs) { if (attribs->type == &at_eventhandler) break; attribs = attribs->nexttype; } while (attribs && attribs->type == &at_eventhandler) { handler_info *tl = (handler_info *)attribs->data.v; if (!strcmp(tl->event, eventname)) { handler_info *tl = (handler_info *)attribs->data.v; handle_triggers(&tl->triggers, data); break; } attribs = attribs->next; } }
static void in_characters_handler(struct terminal_binding *b, char *data, size_t length) { struct term_client *client = b->st; if (client->non_blocking_read) { assert(client->chars_cb != NULL); /* handle triggers */ handle_triggers(client, data, length); /* filter input */ term_filter_apply(client->input_filters, &data, &length); /* call user supplied chars_cb */ client->chars_cb(client->st, data, length); } else { assert(client->readbuf == NULL); client->readbuf = data; client->readbuf_pos = data; client->readbuf_len = length; } }
/** * \brief Blocking read from a terminal. * * \param client Terminal client state. * \param data Buffer to hold read characters. * \param length The number of characters to read. * \param read Number of characters read. This might be less than length if * line_mode is enabled and the end of line was reached or if an * error occurred. * * \return SYS_ERR_OK if successful. * TERM_ERR_IO if an I/O error occurred. * * Dispatches the read if no data is available. */ errval_t term_client_blocking_read(struct term_client *client, char *data, size_t length, size_t *read) { errval_t err; bool eol_reached = false; assert(data != NULL); assert(length > 0); assert(read != NULL); /* * Copy as many characters to the user buffer as he requested but stop if * line mode is enabled and the end of line is reached. */ while ((*read < length) && !(client->line_mode && eol_reached)) { if (client->readbuf == NULL) { /* * Dispatch events on the incoming interface until characters * arrive. */ while (client->readbuf == NULL) { err = event_dispatch(client->read_ws); if (err_is_fail(err)) { return err_push(err, TERM_ERR_IO); } } /* handle echo */ if (client->echo) { err = handle_echo(client, client->readbuf, client->readbuf_len); if (err_is_fail(err)) { return err_push(err, TERM_ERR_IO); } } /* handle triggers */ handle_triggers(client, client->readbuf, client->readbuf_len); /* filter input */ term_filter_apply(client->input_filters, &client->readbuf, &client->readbuf_len); } /* copy data to user supplied buffer */ char *end = client->readbuf + client->readbuf_len; while ((client->readbuf_pos < end) && (*read < length) && !(client->line_mode && eol_reached)) { data[(*read)++] = *client->readbuf_pos; if (client->line_mode && (*client->readbuf_pos == TERM_CLIENT_EOL_CHAR)) { eol_reached = true; } client->readbuf_pos++; } /* free readbuf */ if (client->readbuf_pos == end) { free(client->readbuf); client->readbuf = NULL; client->readbuf_pos = NULL; client->readbuf_len = 0; } } return SYS_ERR_OK; }