Example #1
0
static void run_cache_client(int retry) {
    Trap trap;
    unsigned i;
    unsigned id = current_client.id;
    void * args_copy = NULL;

    assert(id != 0);
    current_cache = NULL;
    cache_miss_cnt = 0;
    def_channel = NULL;
    if (current_client.args_copy) args_copy = current_client.args;
    for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START);
    if (set_trap(&trap)) {
        current_client.client(current_client.args);
        clear_trap(&trap);
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else if (id != current_client.id) {
        trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else {
        if (get_error_code(trap.error) != ERR_CACHE_MISS || cache_miss_cnt == 0 || current_cache == NULL) {
            trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_COMMIT);
        }
        else {
            AbstractCache * cache = current_cache;
            if (cache->wait_list_cnt >= cache->wait_list_max) {
                cache->wait_list_max += 8;
                cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
            }
            if (current_client.args != NULL && !current_client.args_copy) {
                void * mem = loc_alloc(current_client.args_size);
                memcpy(mem, current_client.args, current_client.args_size);
                current_client.args = mem;
                current_client.args_copy = 1;
            }
            if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
            if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg);
            cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_ABORT);
            args_copy = NULL;
        }
        memset(&current_client, 0, sizeof(current_client));
        current_cache = NULL;
        cache_miss_cnt = 0;
        def_channel = NULL;
    }
    if (args_copy != NULL) loc_free(args_copy);
}
Example #2
0
void cache_wait(AbstractCache * cache) {
#else
void cache_wait_dbg(const char * file, int line, AbstractCache * cache) {
#endif
    assert(is_dispatch_thread());
    assert(client_exited == 0);
    if (current_client.client != NULL && cache_miss_cnt == 0) {
        if (cache->wait_list_cnt >= cache->wait_list_max) {
            cache->wait_list_max += 8;
            cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
        }
        if (current_client.args != NULL && !current_client.args_copy) {
            void * mem = loc_alloc(current_client.args_size);
            memcpy(mem, current_client.args, current_client.args_size);
            current_client.args = mem;
            current_client.args_copy = 1;
        }
#ifndef NDEBUG
        current_client.file = file;
        current_client.line = line;
        current_client.time_stamp = time(NULL);
        if (!cache_timer_posted) {
            post_event_with_delay(cache_timer, NULL, 5000000);
            cache_timer_posted = 1;
        }
#endif
        if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
        if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg);
        cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
    }
#ifndef NDEBUG
    else if (current_client.client == NULL) {
        trace(LOG_ALWAYS, "Illegal cache access at %s:%d", file, line);
    }
#endif
    cache_miss_cnt++;
    exception(ERR_CACHE_MISS);
}
Example #3
0
static void command_launch(char * token, Channel * c) {
    int err = 0;
    char encoding[TERM_PROP_DEF_SIZE];
    char pty_type[TERM_PROP_DEF_SIZE];
    const char * args[] = TERM_LAUNCH_ARGS;
    const char * exec = TERM_LAUNCH_EXEC;

    int selfattach = 0;
    ProcessStartParams prms;
    Terminal * term = (Terminal *)loc_alloc_zero(sizeof(Terminal));

    memset(&prms, 0, sizeof(prms));
    json_read_string(&c->inp, pty_type, sizeof(pty_type));
    json_test_char(&c->inp, MARKER_EOA);
    json_read_string(&c->inp, encoding, sizeof(encoding));
    json_test_char(&c->inp, MARKER_EOA);
    prms.envp = read_env(&c->inp);
    json_test_char(&c->inp, MARKER_EOM);

#if !defined(_WIN32) && !defined(__CYGWIN__)
    {
        struct stat st;
        if (err == 0 && stat(exec, &st) != 0) {
            err = errno;
            if (err == ENOENT) {
                static char fnm[FILE_PATH_SIZE];
                /* On some systems (e.g. Free DSB) bash is installed under /usr/local */
                assert(exec[0] == '/');
                snprintf(fnm, sizeof(fnm), "/usr/local%s", exec);
                if (stat(fnm, &st) == 0) {
                    args[0] = exec = fnm;
                    err = 0;
                }
            }
            if (err == ENOENT && strcmp(exec, "/bin/bash") == 0) {
                /* "bash" not found, try "sh" */
                const char * fnm = "/bin/sh";
                if (stat(fnm, &st) == 0) {
                    args[0] = exec = fnm;
                    err = 0;
                }
            }
            if (err) err = set_fmt_errno(err, "Cannot start %s", exec);
        }
    }
    set_terminal_env(&prms.envp, pty_type, encoding, exec);
    prms.dir = getenv("HOME");
    if (prms.dir) prms.dir = tmp_strdup(prms.dir);
#else
    {
        const char * home_drv = getenv("HOMEDRIVE");
        const char * home_dir = getenv("HOMEPATH");
        if (home_drv && home_dir) {
            prms.dir = tmp_strdup2(home_drv, home_dir);
        }
    }
#endif

    prms.exe = exec;
    prms.args = (char **)args;
    prms.service = TERMINALS;
    prms.use_terminal = 1;
    prms.exit_cb = terminal_exited;
    prms.exit_args = term;

    if (err == 0 && start_process(c, &prms, &selfattach, &term->prs) < 0) err = errno;

    if (!err) {
        term->bcg = c->bcg;
        channel_lock_with_msg(term->channel = c, TERMINALS);
        strlcpy(term->pty_type, pty_type, sizeof(term->pty_type));
        strlcpy(term->encoding, encoding, sizeof(term->encoding));
        list_add_first(&term->link, &terms_list);
        assert(find_terminal(get_process_pid(term->prs)) == term);
    }
    else {
        assert(term->prs == NULL);
        loc_free(term);
    }

    /* write result back */
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    if (err) {
        write_stringz(&c->out, "null");
    }
    else {
        write_context(&c->out, get_process_pid(term->prs));
        write_stream(&c->out, 0);
    }
    write_stream(&c->out, MARKER_EOM);
}
static PortServer * create_port_server(Channel * c, PortRedirectionInfo * redir) {
    int sock;
    struct sockaddr_in addr;
    PortAttribute * attr = redir->attrs;
#if defined(_WRS_KERNEL)
    int addrlen;
#else
    socklen_t addrlen;
#endif
    u_short port_number;
    PortServer * server = NULL;
    int is_udp = 0;           /* do we use a server UDP -or TCP- port? */

    while (attr != NULL) {
        if (strcmp(attr->name,  "Config") == 0) {
            ByteArrayInputStream buf;
            char * config;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            config = json_read_alloc_string(inp);
            if (strncasecmp(config, "udp:", strlen("udp:")) == 0) {
                is_udp = 1;
            }
            loc_free(config);
            break;
        }
        attr = attr->next;
    }
    memset((void *) &addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = (u_short) htons(redir->local_port);

    sock = -1;

    if (is_udp) sock = socket(AF_INET, SOCK_DGRAM, 0);
    else if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) set_socket_options(sock); /* set socket options */

    if (sock == -1) return NULL ;

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        if (redir->local_port != 0) {
            memset((void *) &addr, 0, sizeof(addr));
            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
            addr.sin_port = (u_short) 0;
            if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
                perror ("bind");
                goto error;
            }
        } else {
            perror("bind");
            goto error;
        }
    }

    if (!is_udp) {
        if (listen(sock, 16) != 0) goto error;
    }

    /* Get port property in case the default port could not be used or
     * the client specified a port that the system converts to a
     * dynamic port number. */
    addrlen = sizeof addr;
    if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) goto error;
    port_number = (u_short) ntohs(addr.sin_port);

    server = loc_alloc_zero(sizeof(PortServer));
    server->sock = sock;
    server->is_udp = is_udp;
#if defined(SOCK_MAXADDRLEN)
    server->addr_len = SOCK_MAXADDRLEN;
#else
    server->addr_len = 0x1000;
#endif
    server->addr_buf = (struct sockaddr *)loc_alloc(server->addr_len);
    server->local_port = port_number;

    if (!server->is_udp) {
        server->accept_in_progress = 1;

        server->accreq.done = port_server_accept_done;
        server->accreq.client_data = server;
        server->accreq.type = AsyncReqAccept;
        server->accreq.u.acc.sock = sock;
        server->accreq.u.acc.addr = server->addr_buf;
        server->accreq.u.acc.addrlen = server->addr_len;
        async_req_post(&server->accreq);
        }
    else
        {
        /* For UDP, automatically connect to the port since there is no
         * connection request we can detect.
         */
        redir->auto_connect = 1;
        }

    list_add_last(&server->link, &server_list);
    channel_lock_with_msg(server->channel = c, channel_lock_svr_msg);
    snprintf (server->id, sizeof(server->id), "%" PRIu64, port_server_id++);
    return server;
    error:
    closesocket(sock);
    loc_free(server);
    return NULL ;
}
Example #5
0
static PortServer * create_server(Channel * c, PortAttribute * attrs) {
    int sock = -1;
    struct sockaddr_in addr;
    PortAttribute * attr = attrs;
#if defined(_WRS_KERNEL)
    int addrlen;
#else
    socklen_t addrlen;
#endif
    u_short port_number;
    PortServer * server = NULL;
    int is_udp = 0;           /* do we use a server UDP -or TCP- port? */
    char * port_config = NULL;
    int error = 0;
    int auto_connect = 0;
    uint64_t auto_connect_period = 0;
    unsigned int local_port = 0;

    while (attr != NULL) {
        if (strcmp(attr->name,  "Port") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            port_config = json_read_alloc_string(inp);
            if (strncasecmp(port_config, "udp:", strlen("udp:")) == 0) {
                is_udp = 1;
            }
        }
        else if (strcmp(attr->name, "AutoConnect") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            auto_connect = json_read_boolean(inp);
        }
        else if (strcmp(attr->name, "AutoConnectPeriod") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            auto_connect_period = json_read_ulong(inp);
        }
        else if (strcmp(attr->name, "LocalPort") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            local_port = (unsigned int) json_read_uint64(inp);
        }
        attr = attr->next;
    }
    if (port_config == NULL) {
        error = set_errno(ERR_OTHER, "No port configuration is specified");
    }
    if (error == 0) {
        loc_free(port_config);
        memset((void *) &addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addr.sin_port = (u_short) htons(local_port);

        if (is_udp) sock = socket(AF_INET, SOCK_DGRAM, 0);
        else if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) set_socket_options(sock); /* set socket options */

        if (sock == -1) error = errno;
    }

    if (error == 0) {
        if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
            error = errno;
        }
    }

    if (error == 0 && !is_udp) {
        if (listen(sock, 16) != 0) error = errno;
    }

    if (error == 0) {
        /* Get port property in case the default port could not be used or
         * the client specified a port that the system converts to a
         * dynamic port number. */
        addrlen = sizeof addr;
        if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) error = errno;
    }

    if (error == 0) {
        port_number = (u_short) ntohs(addr.sin_port);

        server = (PortServer *)loc_alloc_zero(sizeof(PortServer));
        server->sock = sock;
        server->is_udp = is_udp;
#if defined(SOCK_MAXADDRLEN)
        server->addr_len = SOCK_MAXADDRLEN;
#else
        server->addr_len = 0x1000;
#endif
        server->addr_buf = (struct sockaddr *)loc_alloc(server->addr_len);
        server->local_port = port_number;

        if (!server->is_udp) {
            server->accept_in_progress = 1;
            server->auto_connect = auto_connect;

            server->accreq.done = port_server_accept_done;
            server->accreq.client_data = server;
            server->accreq.type = AsyncReqAccept;
            server->accreq.u.acc.sock = sock;
            server->accreq.u.acc.addr = server->addr_buf;
            server->accreq.u.acc.addrlen = server->addr_len;
            async_req_post(&server->accreq);
            }
        else
            {
            /* For UDP, automatically connect to the port since there is no
             * connection request we can detect.
             */
            server->auto_connect = 1;
            }
        server->auto_connect_period = auto_connect_period;

        list_add_last(&server->link, &server_list);
        channel_lock_with_msg(server->channel = c, channel_lock_svr_msg);
        snprintf (server->id, sizeof(server->id), "PS%" PRIu64, port_server_id++);
        server->attrs = attrs;
    }
    if (error == 0) return server;
    else {
        if (sock != -1) closesocket(sock);
        loc_free(server);
        return NULL ;
    }
}