コード例 #1
0
static void command_eos(char * token, Channel * c) {
    char id[256];
    StreamClient * client = NULL;
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strncpy(r->token, token, sizeof(r->token) - 1);
        list_add_last(&r->link_client, &client->write_requests);
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }
}
コード例 #2
0
ファイル: streamsservice.c プロジェクト: eclipse/tcf.agent
int virtual_stream_eos(Channel * c, char * token, char * id) {
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}
コード例 #3
0
ファイル: streamsservice.c プロジェクト: eclipse/tcf.agent
int virtual_stream_get_data(VirtualStream * stream, char * buf, size_t buf_size, size_t * data_size, int * eos) {
    size_t len;

    assert(stream->magic == STREAM_MAGIC);
    len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len;

    if (len > buf_size) {
        len = buf_size;
        *eos = 0;
    }
    else {
        *eos = stream->eos_inp;
    }
    *data_size = len;
    if (*eos) stream->eos_out = 1;
    if (stream->buf_out + len <= stream->buf_len) {
        memcpy(buf, stream->buf + stream->buf_out, len);
    }
    else {
        size_t x = stream->buf_len - stream->buf_out;
        size_t y = len - x;
        memcpy(buf, stream->buf + stream->buf_out, x);
        memcpy(buf + x, stream->buf, y);
    }
    if (stream->access & VS_ENABLE_REMOTE_WRITE) {
        LINK * l;
        for (l = stream->clients.next; l != &stream->clients; l = l->next) {
            StreamClient * client = stream2client(l);
            if (!list_is_empty(&client->write_requests)) {
                WriteRequest * r = client2write_request(client->write_requests.next);
                size_t done = 0;
                int error = 0;
                if (virtual_stream_add_data(client->stream, r->data + r->offs,
                    r->size - r->offs, &done, r->eos) < 0) error = errno;
                r->offs += done;
                if (error || r->offs >= r->size) {
                    delete_write_request(r, error);
                }
                while (error && !list_is_empty(&client->write_requests)) {
                    r = client2write_request(client->write_requests.next);
                    delete_write_request(r, ERR_COMMAND_CANCELLED);
                }
            }
        }
    }
    if ((stream->access & VS_ENABLE_REMOTE_READ) == 0 && len > 0) {
        stream->buf_out = (stream->buf_out + len) % stream->buf_len;
        assert(!*eos || stream->buf_out == stream->buf_inp);
        if (!stream->space_available_posted) {
            post_event(notify_space_available, stream);
            stream->space_available_posted = 1;
        }
    }
    return 0;
}
コード例 #4
0
static void process_output_streams_callback(VirtualStream * stream, int event_code, void * args) {
    ProcessOutput * out = (ProcessOutput *)args;

    assert(out->vstream == stream);
    if (!out->req_posted) {
        int buf_len = out->req.u.fio.rval;
        int err = 0;
        int eos = 0;

        if (buf_len < 0) {
            buf_len = 0;
            err = out->req.error;
        }
        if (buf_len == 0) eos = 1;
        if (out->prs == NULL) {
            eos = 1;
            err = 0;
        }

        assert(buf_len <= sizeof(out->buf));
        assert(out->buf_pos <= (size_t)buf_len);
        assert(out->req.u.fio.bufp == out->buf);
#ifdef __linux
        if (err == EIO) err = 0;
#endif
        if (err) trace(LOG_ALWAYS, "Can't read process output stream: %d %s", err, errno_to_str(err));

        if (out->buf_pos < (size_t)buf_len || out->eos != eos) {
            size_t done = 0;
            virtual_stream_add_data(stream, out->buf + out->buf_pos, buf_len - out->buf_pos, &done, eos);
            out->buf_pos += done;
            if (eos) out->eos = 1;
        }

        if (out->buf_pos >= (size_t)buf_len) {
            if (!eos) {
                out->req_posted = 1;
                async_req_post(&out->req);
            }
            else if (virtual_stream_is_empty(stream)) {
                if (out->prs != NULL) {
                    if (out == out->prs->out_struct) out->prs->out_struct = NULL;
                    if (out == out->prs->err_struct) out->prs->err_struct = NULL;
                }
                virtual_stream_delete(stream);
                loc_free(out);
            }
        }
    }
}
コード例 #5
0
static void command_write(char * token, Channel * c) {
    char id[256];
    StreamClient * client = NULL;
    long size = 0;
    long offs = 0;
    char * data = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    size = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;

    {
        JsonReadBinaryState state;
        unsigned data_pos = 0;

        if (!err && !list_is_empty(&client->write_requests)) data = loc_alloc(size);

        json_read_binary_start(&state, &c->inp);
        for (;;) {
            if (data != NULL) {
                size_t rd = json_read_binary_data(&state, data + data_pos, size - offs - data_pos);
                if (rd == 0) break;
                data_pos += rd;
            }
            else {
                char buf[256];
                size_t rd = json_read_binary_data(&state, buf, sizeof(buf));
                if (rd == 0) break;
                if (!err) {
                    size_t done = 0;
                    if (virtual_stream_add_data(client->stream, buf, rd, &done, 0) < 0) err = errno;
                    assert(done <= rd);
                    offs += done;
                    if (!err && done < rd) {
                        data = loc_alloc(size - offs);
                        memcpy(data, buf + done, rd - done);
                        data_pos = rd - done;
                    }
                }
            }
        }
        json_read_binary_end(&state);
    }

    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if (data != NULL) {
        WriteRequest * r = loc_alloc_zero(sizeof(WriteRequest));
        list_init(&r->link_client);
        r->client = client;
        r->data = data;
        r->size = size - offs;
        strncpy(r->token, token, sizeof(r->token) - 1);
        list_add_last(&r->link_client, &client->write_requests);
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }
}
コード例 #6
0
ファイル: streamsservice.c プロジェクト: eclipse/tcf.agent
int virtual_stream_write(Channel * c, char * token, char * id, size_t size, InputStream * inp) {
    char * data = NULL;
    int err = 0;
    long offs = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;

    {
        JsonReadBinaryState state;
        size_t data_pos = 0;

        if (!err && !list_is_empty(&client->write_requests)) data = (char *)loc_alloc(size);

        json_read_binary_start(&state, inp);
        for (;;) {
            if (data != NULL) {
                size_t rd = json_read_binary_data(&state, data + data_pos, size - offs - data_pos);
                if (rd == 0) break;
                data_pos += rd;
            }
            else {
                char buf[256];
                size_t rd = json_read_binary_data(&state, buf, sizeof(buf));
                if (rd == 0) break;
                if (!err) {
                    size_t done = 0;
                    if (virtual_stream_add_data(client->stream, buf, rd, &done, 0) < 0) err = errno;
                    assert(done <= rd);
                    offs += done;
                    if (!err && done < rd) {
                        data = (char *)loc_alloc(size - offs);
                        memcpy(data, buf + done, rd - done);
                        data_pos = rd - done;
                    }
                }
            }
        }
        json_read_binary_end(&state);
    }

    if (data != NULL) {
        WriteRequest * r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest));
        list_init(&r->link_client);
        r->client = client;
        r->data = data;
        r->size = size - offs;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}