Beispiel #1
0
//! [uart write]
static bool
send_blob(struct sol_blob *blob)
{
    int err;
    bool r = true;

    //Actually write the blob into UART bus
    err = sol_uart_feed(producer, blob);
    if (err < 0) {
        //Oh no, there's no more space left.
        if (err == -ENOSPC) {
            pending_blob = blob;
            printf("No space left in the tx buffer - saving blob for later. Data: %.*s\n",
                SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(pending_blob)));
        } else {
            fprintf(stderr, "Could not not perform an UART write - Reason: %s\n",
                sol_util_strerrora(-r));
            r = false;
            sol_blob_unref(blob);
        }
    } else {
        sol_blob_unref(blob);
        if (blob == pending_blob)
            pending_blob = NULL; //Flag that data production can start once again!
    }

    return r;
}
Beispiel #2
0
static bool
on_err_read(void *data, int fd, uint32_t active_flags)
{
    struct subprocess_data *mdata = data;
    struct sol_blob *blob = NULL;
    bool eof = true;
    int err = 0;

    if (active_flags & SOL_FD_FLAGS_ERR)
        err = -EBADF;
    else
        err = child_read(&blob, &eof, mdata->pipes.err[0]);

    if (eof || err < 0) {
        mdata->watches.err = NULL;
        if (err < 0)
            return false;
    }

    sol_flow_send_blob_packet(mdata->node, SOL_FLOW_NODE_TYPE_PROCESS_SUBPROCESS__OUT__STDERR, blob);
    sol_blob_unref(blob);
    if (eof)
        return false;
    return true;
}
Beispiel #3
0
static bool
on_write(void *data, int fd, uint32_t active_flags)
{
    struct subprocess_data *mdata = data;
    int err = 0;

    if (active_flags & SOL_FD_FLAGS_ERR)
        err = -EBADF;
    else
        err = out_write(mdata);

    if (err < 0) {
        uint16_t i;
        struct write_data *w;

        SOL_VECTOR_FOREACH_IDX (&mdata->write_data, w, i)
            sol_blob_unref(w->blob);
        sol_vector_clear(&mdata->write_data);
    }

    if (mdata->write_data.len == 0) {
        mdata->watches.out = NULL;
        return false;
    }

    return true;
}
Beispiel #4
0
void
process_subprocess_close(struct sol_flow_node *node, void *data)
{
    struct subprocess_data *mdata = data;

    if (mdata->fork_run)
        sol_platform_linux_fork_run_stop(mdata->fork_run);

    if (mdata->watches.in)
        sol_fd_del(mdata->watches.in);
    if (mdata->watches.err)
        sol_fd_del(mdata->watches.err);
    if (mdata->watches.out) {
        struct write_data *w;
        uint16_t i;

        sol_fd_del(mdata->watches.out);
        SOL_VECTOR_FOREACH_IDX (&mdata->write_data, w, i)
            sol_blob_unref(w->blob);
        sol_vector_clear(&mdata->write_data);
    }

    close(mdata->pipes.in[0]);
    close(mdata->pipes.in[1]);
    close(mdata->pipes.err[0]);
    close(mdata->pipes.err[1]);
    close(mdata->pipes.out[0]);
    close(mdata->pipes.out[1]);

    free(mdata->command);
}
Beispiel #5
0
int
process_subprocess_in_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    struct subprocess_data *mdata = data;
    struct sol_blob *blob;
    struct write_data *w;
    int ret;

    SOL_NULL_CHECK(mdata->fork_run, -EINVAL);
    ret = sol_flow_packet_get_blob(packet, &blob);
    SOL_INT_CHECK(ret, < 0, ret);

    w = sol_vector_append(&mdata->write_data);
    SOL_NULL_CHECK(w, -ENOMEM);

    w->offset = 0;
    w->blob = sol_blob_ref(blob);
    if (mdata->write_data.len > 1)
        return 0;

    mdata->watches.out = sol_fd_add(mdata->pipes.out[1], SOL_FD_FLAGS_OUT | SOL_FD_FLAGS_ERR, on_write, mdata);
    if (!mdata->watches.out) {
        sol_blob_unref(w->blob);
        sol_vector_del_last(&mdata->write_data);
        return -1;
    }

    return 0;
}
Beispiel #6
0
static void
on_feed_done_cb(void *data, struct sol_message_digest *md, struct sol_blob *input)
{
    struct update_get_hash_handle *handle = data;
    char buf[CHUNK_SIZE], *blob_backend = NULL;
    struct sol_blob *blob = NULL;
    size_t size;
    bool last;
    int r;

    size = fread(buf, 1, sizeof(buf), handle->file);
    if (ferror(handle->file)) {
        SOL_WRN("Could not read file for feed hash algorithm");
        goto err;
    }

    last = feof(handle->file);

    /* TODO Maybe this is a bug on sol_message_digest? Keeps calling on_feed_done
     * after send last chunk */
    if (!size && last && input) {
        SOL_WRN("Nothing more to feed hash algorithm, ignoring on_feed_done request");
        return;
    }

    blob_backend = malloc(size);
    SOL_NULL_CHECK_GOTO(blob_backend, err);

    blob = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL, blob_backend, size);
    SOL_NULL_CHECK_GOTO(blob, err);

    memcpy(blob_backend, buf, size);

    r = sol_message_digest_feed(md, blob, last);
    SOL_INT_CHECK_GOTO(r, < 0, err);

    sol_blob_unref(blob);
    return;

err:
    SOL_WRN("Could not feed data to check update file hash");
    free(blob_backend);
    sol_blob_unref(blob);
    sol_message_digest_del(md);
    handle->cb((void *)handle->user_data, -EINVAL, NULL);
    delete_handle(handle);
}
static void
consumed_cb(void *data, uint32_t id, struct sol_blob *message)
{
    printf("x86 receiving consumed confirmation id: %" PRIu32 " %p data: %s\n",
           id, message->mem, (char *)message->mem);
    sol_blob_unref(message);
    printf("After unref %p\n", message);
}
Beispiel #8
0
static void
file_reader_unload(struct file_reader_data *mdata)
{
    if (mdata->idler) {
        sol_idle_del(mdata->idler);
        mdata->idler = NULL;
    }
    if (mdata->content_blob) {
        sol_blob_unref(mdata->content_blob);
        mdata->content_blob = NULL;
    }
    if (mdata->reader_blob) {
        sol_blob_unref(mdata->reader_blob);
        mdata->reader_blob = NULL;
    }
    SOL_DBG("unloaded path=\"%s\"", mdata->path ? mdata->path : "");
    free(mdata->path);
}
Beispiel #9
0
static void
empty_receiver(void *data, uint32_t id, struct sol_blob *message)
{
    struct sol_flow_node *node = data;

    sol_flow_send_empty_packet(node,
        SOL_FLOW_NODE_TYPE_IPM_EMPTY_READER__OUT__OUT);
    sol_blob_unref(message);
}
Beispiel #10
0
static void
direction_vector_receiver(void *data, uint32_t id, struct sol_blob *message)
{
    struct sol_flow_node *node = data;

    sol_flow_send_direction_vector_packet(node,
        SOL_FLOW_NODE_TYPE_IPM_DIRECTION_VECTOR_READER__OUT__OUT, message->mem);
    sol_blob_unref(message);
}
Beispiel #11
0
static void
rgb_receiver(void *data, uint32_t id, struct sol_blob *message)
{
    struct sol_flow_node *node = data;

    sol_flow_send_rgb_packet(node,
        SOL_FLOW_NODE_TYPE_IPM_RGB_READER__OUT__OUT, message->mem);
    sol_blob_unref(message);
}
Beispiel #12
0
static void
boolean_receiver(void *data, uint32_t id, struct sol_blob *message)
{
    struct sol_flow_node *node = data;

    sol_flow_send_bool_packet(node,
        SOL_FLOW_NODE_TYPE_IPM_BOOLEAN_READER__OUT__OUT, *(bool *)message->mem);
    sol_blob_unref(message);
}
static bool
unref_cb(void *data)
{
    struct sol_blob *blob = data;

    printf("ARC unrefing %p\n", blob->mem);
    sol_blob_unref(blob);

    return false;
}
static bool
unref_cb(void *data)
{
    struct sol_blob *blob = data;

    printf("x86 unrefing %p - %s\n", blob->mem, (char *)blob->mem);
    sol_blob_unref(blob);

    return false;
}
Beispiel #15
0
static void
byte_receiver(void *data, uint32_t id, struct sol_blob *message)
{
    struct sol_flow_node *node = data;

    sol_flow_send_byte_packet(node,
        SOL_FLOW_NODE_TYPE_IPM_BYTE_READER__OUT__OUT,
        *(unsigned char *)message->mem);
    sol_blob_unref(message);
}
Beispiel #16
0
static bool
on_stdin(void *data, int fd, uint32_t flags)
{
    uint16_t i;
    struct sol_http_progressive_response *sse;
    struct sol_buffer value = SOL_BUFFER_INIT_EMPTY;

    if (flags & (SOL_FD_FLAGS_ERR | SOL_FD_FLAGS_HUP)) {
        fprintf(stderr, "ERROR: Something wrong happened with file descriptor: %d\n", fd);
        goto err;
    }

    if (flags & SOL_FD_FLAGS_IN) {
        int err;
        struct sol_blob *blob;

        /* this will loop trying to read as much data as possible to buffer. */
        err = sol_util_load_file_fd_buffer(fd, &value);
        if (err < 0) {
            fprintf(stderr, "ERROR: failed to read from stdin: %s\n",
                sol_util_strerrora(-err));
            goto err;
        }

        if (value.used == 0) {
            /* no data usually means ^D on the terminal, quit the application */
            printf("no data on stdin, quitting.\n");
            should_quit = true;
            SOL_PTR_VECTOR_FOREACH_IDX (&responses, sse, i)
                sol_http_progressive_response_del(sse, true);
            goto end;
        }

        blob = sol_buffer_to_blob(&value);
        if (!blob) {
            fprintf(stderr, "Could not alloc the blob data\n");
            goto err;
        }
        SOL_PTR_VECTOR_FOREACH_IDX (&responses, sse, i)
            sol_http_progressive_response_sse_feed(sse, blob);
        sol_blob_unref(blob);
    }

    sol_buffer_fini(&value);
    return true;

err:
    sol_quit_with_code(EXIT_FAILURE);
end:
    stdin_watch = NULL;
    sol_buffer_fini(&value);
    return false;
}
Beispiel #17
0
SOL_API void
sol_blob_set_parent(struct sol_blob *blob, struct sol_blob *parent)
{
    SOL_BLOB_CHECK(blob);

    if (parent) {
        SOL_BLOB_CHECK(parent);
        sol_blob_ref(parent);
    }

    if (blob->parent)
        sol_blob_unref(blob->parent);

    blob->parent = parent;
}
Beispiel #18
0
SOL_API void
sol_blob_unref(struct sol_blob *blob)
{
    SOL_BLOB_CHECK(blob);
    blob->refcnt--;
    if (blob->refcnt > 0)
        return;

    if (blob->parent)
        sol_blob_unref(blob->parent);

    if (blob->type->free)
        blob->type->free(blob);
    else
        free(blob);
}
static bool
timeout_send_cb(void *data)
{
    int r;
    char *str = strdup(samples[count % 4]);
    struct sol_blob *message = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL,
        str, strlen(str) + 1);

    printf("ARC sending %s - %p\n", (char *)message->mem, message->mem);
    r = sol_ipm_send(MESSAGE_ID, message);
    if (r < 0) {
        printf("ARC could not send message: %d\n", r);
    }

    sol_blob_unref(message); /* Unref as we don't care about when it's consumed.
                                Let blob be unref'ed and be happy happy*/

    count++;
    return true;
}
Beispiel #20
0
static int
out_write(struct subprocess_data *mdata)
{
    int ret = 0;
    struct timespec start = sol_util_timespec_get_current();

    while (mdata->write_data.len) {
        struct timespec now = sol_util_timespec_get_current();
        struct timespec elapsed;
        struct write_data *w = sol_vector_get(&mdata->write_data, 0);
        ssize_t r;

        sol_util_timespec_sub(&now, &start, &elapsed);
        if (elapsed.tv_sec > 0 ||
            elapsed.tv_nsec > (time_t)CHUNK_MAX_TIME_NS)
            break;

        r = write(mdata->pipes.out[1], (uint8_t *)w->blob->mem + w->offset, w->blob->size - w->offset);
        if (r > 0) {
            w->offset += r;
        } else if (r < 0) {
            if (errno == EINTR)
                continue;
            else if (errno == EAGAIN)
                break;
            else {
                ret = -errno;
                break;
            }
        }

        if (w->blob->size <= w->offset) {
            sol_blob_unref(w->blob);
            sol_vector_del(&mdata->write_data, 0);
        }
    }

    return ret;
}
Beispiel #21
0
static int
file_reader_load(struct file_reader_data *mdata)
{
    struct sol_file_reader *reader;
    struct sol_str_slice slice;

    if (!mdata->path)
        return 0;

    reader = sol_file_reader_open(mdata->path);
    if (!reader) {
        sol_flow_send_error_packet(mdata->node, errno,
                                   "Could not load \"%s\": %s", mdata->path, sol_util_strerrora(errno));
        return -errno;
    }
    slice = sol_file_reader_get_all(reader);

    SOL_DBG("loaded path=\"%s\", data=%p, len=%zd", mdata->path, slice.data, slice.len);
    mdata->reader_blob = sol_blob_new(&file_reader_blob_type, NULL,
                                      reader, sizeof(reader));
    SOL_NULL_CHECK_GOTO(mdata->reader_blob, err_reader);

    mdata->content_blob = sol_blob_new(SOL_BLOB_TYPE_NOFREE,
                                       mdata->reader_blob,
                                       slice.data, slice.len);
    SOL_NULL_CHECK_GOTO(mdata->content_blob, err_content);

    return sol_flow_send_blob_packet(mdata->node,
                                     SOL_FLOW_NODE_TYPE_FILE_READER__OUT__OUT,
                                     mdata->content_blob);

err_content:
    sol_blob_unref(mdata->reader_blob);
err_reader:
    sol_file_reader_close(reader);
    return -ENOMEM;
}
Beispiel #22
0
static void
on_fork_exit(void *data, uint64_t pid, int status)
{
    struct subprocess_data *mdata = data;

    mdata->fork_run = NULL;
    if (mdata->watches.in)
        sol_fd_del(mdata->watches.in);
    if (mdata->watches.err)
        sol_fd_del(mdata->watches.err);
    if (mdata->watches.out) {
        struct write_data *w;
        uint16_t i;
        sol_fd_del(mdata->watches.out);
        SOL_VECTOR_FOREACH_IDX (&mdata->write_data, w, i)
            sol_blob_unref(w->blob);
        sol_vector_clear(&mdata->write_data);
    }

    mdata->watches.in = NULL;
    mdata->watches.err = NULL;
    mdata->watches.out = NULL;
    sol_flow_send_irange_value_packet(mdata->node, SOL_FLOW_NODE_TYPE_PROCESS_SUBPROCESS__OUT__STATUS, status);
}
Beispiel #23
0
static void
startup(void)
{
    const char *algorithm = "sha256";
    const char *key = NULL;
    char **argv = sol_argv();
    int i, argc = sol_argc();
    size_t chunk_size = -1;

    if (argc < 2) {
        fprintf(stderr,
            "Usage:\n\t%s [-a <algorithm>] [-c chunk_size] [-k key] <file1> .. <fileN>\n", argv[0]);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    for (i = 1; i < argc; i++) {
        struct feed_ctx *ctx;
        struct sol_message_digest_config cfg = {
            SOL_SET_API_VERSION(.api_version = SOL_MESSAGE_DIGEST_CONFIG_API_VERSION, )
            .algorithm = algorithm,
            .on_feed_done = on_feed_done,
            .on_digest_ready = on_digest_ready,
        };
        struct sol_file_reader *fr;
        struct sol_blob *blob;
        struct sol_message_digest *mdh;
        int r;

        if (argv[i][0] == '-') {
            if (argv[i][1] == 'a') {
                if (i + 1 < argc) {
                    algorithm = argv[i + 1];
                    i++;
                    continue;
                } else
                    fputs("ERROR: argument -a missing value.\n", stderr);
            } else if (argv[i][1] == 'k') {
                if (i + 1 < argc) {
                    key = argv[i + 1];
                    i++;
                    continue;
                } else
                    fputs("ERROR: argument -a missing value.\n", stderr);
            } else if (argv[i][1] == 'c') {
                if (i + 1 < argc) {
                    chunk_size = atoi(argv[i + 1]);
                    i++;
                    continue;
                } else
                    fputs("ERROR: argument -c missing value.\n", stderr);
            } else
                fprintf(stderr, "ERROR: unknown option %s\n", argv[i]);
            sol_quit_with_code(EXIT_FAILURE);
            return;
        }

        fr = sol_file_reader_open(argv[i]);
        if (!fr) {
            fprintf(stderr, "ERROR: could not open file '%s': %s\n",
                argv[i], sol_util_strerrora(errno));
            continue;
        }

        blob = sol_file_reader_to_blob(fr);
        if (!blob) {
            fprintf(stderr, "ERROR: could not create blob for file '%s'\n",
                argv[i]);
            continue;
        }

        cfg.data = ctx = calloc(1, sizeof(struct feed_ctx));
        if (!ctx) {
            fprintf(stderr, "ERROR: could not allocate context memory "
                "to process file '%s'\n", argv[i]);
            sol_blob_unref(blob);
            continue;
        }

        ctx->file = argv[i];
        ctx->start = sol_util_timespec_get_current();
        ctx->done = 0;
        ctx->chunk_size = chunk_size;


        if (key)
            cfg.key = sol_str_slice_from_str(key);

        mdh = sol_message_digest_new(&cfg);
        if (!mdh) {
            fprintf(stderr, "ERROR: could not create message digest for "
                " algorithm \"%s\": %s\n",
                algorithm, sol_util_strerrora(errno));
            sol_blob_unref(blob);
            free(ctx);
            continue;
        }

        if (chunk_size <= 0) {
            r = sol_message_digest_feed(mdh, blob, true);
            if (r < 0) {
                fprintf(stderr, "ERROR: could not feed message for "
                    " algorithm \"%s\": %s\n",
                    algorithm, sol_util_strerrora(-r));
                sol_blob_unref(blob);
                sol_message_digest_del(mdh);
                free(ctx);
                continue;
            }
        } else {
            size_t offset = 0;
            while (offset < blob->size) {
                size_t remaining = blob->size - offset;
                size_t clen = remaining > chunk_size ? chunk_size : remaining;
                uint8_t *cmem = (uint8_t *)blob->mem + offset;
                bool is_last = offset + clen == blob->size;
                struct sol_blob *chunk = sol_blob_new(&SOL_BLOB_TYPE_NO_FREE_DATA,
                    blob, cmem, clen);
                if (!chunk) {
                    fprintf(stderr, "ERROR: could not create chunk blob at "
                        "mem %p, size=%zd\n", cmem, clen);
                    sol_blob_unref(blob);
                    sol_message_digest_del(mdh);
                    free(ctx);
                    continue;
                }

                r = sol_message_digest_feed(mdh, chunk, is_last);
                if (r < 0) {
                    fprintf(stderr, "ERROR: could not feed chunk for "
                        " algorithm \"%s\": %s\n",
                        algorithm, sol_util_strerrora(-r));
                    sol_blob_unref(blob);
                    sol_blob_unref(chunk);
                    sol_message_digest_del(mdh);
                    free(ctx);
                    continue;
                }

                sol_blob_unref(chunk);
                offset += clen;
            }
        }

        sol_blob_unref(blob);
        pending++;
    }