예제 #1
0
파일: event.c 프로젝트: Xolgrim/server
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;
    }
}
예제 #2
0
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;
    }
}
예제 #3
0
/**
 * \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;
}