Ejemplo n.º 1
0
static void
create_seconds(void)
{
    const struct sol_flow_node_type **type;
    struct sol_flow_node_named_options named_opts = {};
    const char *strv_opts[] = {
        "send_initial_packet=1",
        NULL
    };
    struct sol_flow_node_options *opts;
    int err;

    err = sol_flow_get_node_type("wallclock",
        SOL_FLOW_NODE_TYPE_WALLCLOCK_SECOND, &type);
    if (err < 0) {
        fputs("could not find type: wallclock/second\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    seconds_port_enabled = sol_flow_node_find_port_in(*type, "ENABLED");
    if (seconds_port_enabled == UINT16_MAX) {
        fputs("ERROR: couldn't find ouput port by name: ENABLED\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }
    seconds_port_out = sol_flow_node_find_port_out(*type, "OUT");
    if (seconds_port_out == UINT16_MAX) {
        fputs("ERROR: couldn't find ouput port by name: OUT\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    err = sol_flow_node_named_options_init_from_strv(&named_opts, *type, strv_opts);
    if (err < 0) {
        fputs("could not parse options for wallclock/second\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    err = sol_flow_node_options_new(*type, &named_opts, &opts);
    sol_flow_node_named_options_fini(&named_opts);
    if (err < 0) {
        fputs("could not create options for wallclock/second\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    seconds = sol_flow_single_new("seconds", *type, opts,
        SOL_FLOW_SINGLE_CONNECTIONS(seconds_port_enabled),
        SOL_FLOW_SINGLE_CONNECTIONS(seconds_port_out),
        on_seconds_packet, NULL);
    sol_flow_node_options_del(*type, opts);
}
Ejemplo n.º 2
0
static bool
startup(void *data)
{
    bool finished = true;
    int result = EXIT_FAILURE;

    the_runner = runner_new(args.filename);
    if (!the_runner)
        goto end;

    if (args.check_only) {
        printf("file: '%s' - Syntax OK\n", args.filename);
        result = EXIT_SUCCESS;
        goto end;
    }

    if (runner_run(the_runner) < 0) {
        SOL_ERR("Failed to run");
        goto end;
    }

    finished = false;

end:
    if (finished)
        sol_quit_with_code(result);

    return false;
}
static bool
on_watchdog(void *data)
{
    SOL_WRN("watchdog expired - mainloop integration failed");
    sol_quit_with_code(EXIT_FAILURE);
    return false;
}
Ejemplo n.º 4
0
static void
fail(const struct sol_flow_node *node)
{
    mark_done(node);
    SOL_ERR("test/result node '%s' failed", sol_flow_node_get_id(node));
    sol_quit_with_code(EXIT_FAILURE);
}
Ejemplo n.º 5
0
static bool
on_stdin(void *data, int fd, uint32_t flags)
{
    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;

        value.used = 0;
        /* 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 */
            puts("no data on stdin, quitting.");
            sol_quit();
        } else {
            printf("Now serving %zd bytes:\n--BEGIN--\n%.*s\n--END--\n",
                value.used, SOL_STR_SLICE_PRINT(sol_buffer_get_slice(&value)));
        }
    }

    return true;

err:
    sol_quit_with_code(EXIT_FAILURE);
    return false;
}
Ejemplo n.º 6
0
static bool
startup(void *data)
{
    bool finished = true;
    int result = EXIT_FAILURE;
    struct sol_ptr_vector *memory_maps;

    str_arena = sol_arena_new();
    if (!str_arena) {
        fprintf(stderr, "Cannot create str arena\n");
        goto end;
    }

    if (args.execute_type) {
        the_runner = runner_new_from_type(args.name, args.options);
    } else {
        the_runner = runner_new_from_file(args.name, args.options,
                                          &args.fbp_search_paths);
    }

    if (!the_runner)
        goto end;

    if (args.check_only) {
        printf("'%s' - Syntax OK\n", args.name);
        result = EXIT_SUCCESS;
        goto end;
    }

    if (args.provide_sim_nodes) {
        int err;
        err = runner_attach_simulation(the_runner);
        if (err < 0) {
            fprintf(stderr, "Cannot attach simulation nodes\n");
            goto end;
        }
    }

    if (sol_conffile_resolve_memmap(&memory_maps)) {
        SOL_ERR("Couldn't resolve memory mappings on config file");
        goto end;
    }
    if (memory_maps)
        load_memory_maps(memory_maps);

    if (runner_run(the_runner) < 0) {
        fprintf(stderr, "Failed to run\n");
        goto end;
    }

    finished = false;

end:
    if (finished)
        sol_quit_with_code(result);

    return false;
}
Ejemplo n.º 7
0
static void
startup(void)
{
    session = sol_bt_enable(enabled, NULL);
    if (!session) {
        SOL_WRN("Couldn't create a Bluetooth session");
        sol_quit_with_code(-ENOMEM);
    }
}
Ejemplo n.º 8
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;
}
static void
startup(void)
{
    guint id;

    if (pipe2(pfd, O_CLOEXEC) < 0) {
        SOL_WRN("pipe()");
        goto error;
    }

    if (!sol_glib_integration()) {
        SOL_WRN("sol_glib_integration()");
        goto error;
    }

    fork_run = sol_platform_linux_fork_run(on_fork, on_child_exit, NULL);
    if (!fork_run) {
        SOL_WRN("sol_platform_linux_fork_run()");
        goto error;
    }

    id = g_idle_add(on_idle, NULL);
    if (id == 0) {
        SOL_WRN("g_idle_add()");
        goto error;
    }

    id = g_timeout_add(100, on_timeout, NULL);
    if (id == 0) {
        SOL_WRN("g_timeout_add()");
        goto error;
    }

    id = g_unix_fd_add(pfd[0], G_IO_IN, on_fd, NULL);
    if (id == 0) {
        SOL_WRN("g_unix_fd_add()");
        goto error;
    }

    sol_timeout_add(5000, on_watchdog, NULL);
    return;

error:
    sol_quit_with_code(EXIT_FAILURE);
    return;
}
Ejemplo n.º 10
0
static void
create_minutes(void)
{
    const struct sol_flow_node_type **type;
    struct sol_flow_node_named_options named_opts = {};
    const char *strv_opts[] = {
        "send_initial_packet=1",
        NULL
    };
    struct sol_flow_node_options *opts;
    int err;

    /* Resolves the type based on its name. This will take care of
     * built-in modules and external modules, loading on demand as
     * required. This macro also handles static-compiles, so the
     * second parameter is the C symbol to be used in such case.
     */
    err = sol_flow_get_node_type("wallclock",
        SOL_FLOW_NODE_TYPE_WALLCLOCK_MINUTE, &type);
    if (err < 0) {
        fputs("could not find type: wallclock/minute\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    /* For efficiency matters Soletta doesn't work with port names,
     * rather using port indexes. If
     * SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED, then we can resolve
     * strings to numbers, otherwise it is required to check the port
     * numbers, which are often available in the header file such as
     * sol-flow/wallclock.h such as
     * SOL_FLOW_NODE_TYPE_WALLCLOCK_MINUTE__OUT__OUT.
     */
    minutes_port_enabled = sol_flow_node_find_port_in(*type, "ENABLED");
    if (minutes_port_enabled == UINT16_MAX) {
        fputs("ERROR: couldn't find ouput port by name: ENABLED\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }
    minutes_port_out = sol_flow_node_find_port_out(*type, "OUT");
    if (minutes_port_out == UINT16_MAX) {
        fputs("ERROR: couldn't find ouput port by name: OUT\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    /* wallclock/minute takes a boolean option send_initial_packet.
     * We have couple of options to create it:
     *
     * 1 - include sol-flow/wallclock.h, declare a variable of type
     *     struct sol_flow_node_type_wallclock_minute_options and fill
     *     its members. This requires sol-flow/wallclock.h to be
     *     avaiable, but is more efficient since goes straight to the
     *     point, no parsing or memory allocations. It would look
     *     like:
     *
     *        #include <sol-flow/wallclock.h>
     *
     *        struct sol_flow_node_type_wallclock_minute_options opts =
     *           SOL_FLOW_NODE_TYPE_WALLCLOCK_MINUTE_OPTIONS_DEFAULTS(
     *              .send_initial_packet = true);
     *
     * 2 - access type->options_size,
     *     type->default_options and
     *     type->description->options and manually
     *     create the structure in runtime. This demands
     *     SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED, but may be useful
     *     when converting from a different representation, like a
     *     language binding such as JavaScript or Python where one can
     *     get an object, hashmap or dictionary and convert straight
     *     to the C structure needed by the flow node type.
     *
     * 3 - use helper sol_flow_node_named_options_init_from_strv() and
     *     sol_flow_node_options_new(), giving it an array of
     *     "key=value" strings. It will do the work described in #2
     *     for us, thus also depends on
     *     SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED.
     *
     * We'll use approach #3 since it is simpler. Language bindings
     * should go with option #2 and those that want to squeeze the
     * size and get performance should consider #1.
     */
    err = sol_flow_node_named_options_init_from_strv(&named_opts, *type, strv_opts);
    if (err < 0) {
        fputs("could not parse options for wallclock/minute\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    /* convert the named options in the actual options structure */
    err = sol_flow_node_options_new(*type, &named_opts, &opts);
    sol_flow_node_named_options_fini(&named_opts);
    if (err < 0) {
        fputs("could not create options for wallclock/minute\n", stderr);
        sol_quit_with_code(EXIT_FAILURE);
        return;
    }

    /* Build the single node wrapping the wanted 'wallclock/minute'.
     * For most matters the single node behaves like the inner node,
     * it will copy the descriptions and options.
     *
     * The difference is that if you call sol_flow_send_packet() on
     * its input ports, it will forward the packet to the inner
     * node. Likewise, packets originated at the outgoing ports of the
     * inner node will be delivered through the process callback
     * (on_packet()) provided to the single node.
     *
     * Note that ports you want to send (in) or receive (out) packets
     * must be connected with the connected_ports_in and
     * connected_ports_out parameters, or later with
     * sol_flow_single_port_in_connect() and
     * sol_flow_single_port_out_connect().
     */
    minutes = sol_flow_single_new("minutes", *type, opts,
        SOL_FLOW_SINGLE_CONNECTIONS(minutes_port_enabled),
        SOL_FLOW_SINGLE_CONNECTIONS(minutes_port_out),
        on_minutes_packet, NULL);
    sol_flow_node_options_del(*type, opts);
}
Ejemplo n.º 11
0
SOL_API void
sol_quit(void)
{
    sol_quit_with_code(EXIT_SUCCESS);
}
Ejemplo n.º 12
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++;
    }