提交 c3b7bb58 authored 作者: Shane Bryldt's avatar Shane Bryldt 提交者: Mike Jerris

FS-9952: Rewrote core code to utilize state machine driven system based on…

FS-9952: Rewrote core code to utilize state machine driven system based on discussions, code compiles but completely untested currently
上级 b24eb4d7
......@@ -11,14 +11,16 @@ libunqlite_la_CFLAGS = -DUNQLITE_ENABLE_THREADS
libunqlite_la_LIBADD = -lpthread
lib_LTLIBRARIES = libblade.la
libblade_la_SOURCES = src/blade.c src/blade_stack.c src/blade_peer.c src/blade_service.c src/bpcp.c src/blade_datastore.c
libblade_la_SOURCES = src/blade.c src/blade_stack.c src/bpcp.c src/blade_datastore.c
libblade_la_SOURCES += src/blade_message.c src/blade_rpcproto.c
libblade_la_SOURCES += src/blade_identity.c src/blade_module.c src/blade_connection.c src/blade_module_wss.c
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm -lconfig $(AM_LDFLAGS)
libblade_la_LIBADD = libunqlite.la
library_includedir = $(prefix)/include
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h src/include/blade_peer.h src/include/blade_service.h
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h
library_include_HEADERS += src/include/bpcp.h src/include/blade_datastore.h src/include/blade_message.h src/include/blade_rpcproto.h
library_include_HEADERS += src/include/blade_identity.h src/include/blade_module.h src/include/blade_connection.h
library_include_HEADERS += src/include/unqlite.h test/tap.h
tests: libblade.la
......
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_connection_s {
blade_handle_t *handle;
ks_pool_t *pool;
void *transport_data;
blade_transport_callbacks_t *transport_callbacks;
ks_bool_t shutdown;
// @todo add auto generated UUID
ks_thread_t *state_thread;
blade_connection_state_t state;
ks_q_t *sending;
ks_q_t *receiving;
};
void *blade_connection_state_thread(ks_thread_t *thread, void *data);
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP,
blade_handle_t *bh,
void *transport_data,
blade_transport_callbacks_t *transport_callbacks)
{
blade_connection_t *bc = NULL;
ks_pool_t *pool = NULL;
ks_assert(bcP);
ks_assert(bh);
ks_assert(transport_data);
ks_assert(transport_callbacks);
pool = blade_handle_pool_get(bh);
bc = ks_pool_alloc(pool, sizeof(blade_connection_t));
bc->handle = bh;
bc->pool = pool;
bc->transport_data = transport_data;
bc->transport_callbacks = transport_callbacks;
ks_q_create(&bc->sending, pool, 0);
ks_q_create(&bc->receiving, pool, 0);
*bcP = bc;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP)
{
blade_connection_t *bc = NULL;
ks_assert(bcP);
ks_assert(*bcP);
bc = *bcP;
blade_connection_shutdown(bc);
ks_q_destroy(&bc->sending);
ks_q_destroy(&bc->receiving);
ks_pool_free(bc->pool, bcP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc)
{
ks_assert(bc);
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_NONE);
if (ks_thread_create_ex(&bc->state_thread,
blade_connection_state_thread,
bc,
KS_THREAD_FLAG_DEFAULT,
KS_THREAD_DEFAULT_STACK,
KS_PRI_NORMAL,
bc->pool) != KS_STATUS_SUCCESS) {
// @todo error logging
blade_connection_disconnect(bc);
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc)
{
ks_assert(bc);
if (bc->state_thread) {
bc->shutdown = KS_TRUE;
ks_thread_join(bc->state_thread);
ks_pool_free(bc->pool, &bc->state_thread);
bc->shutdown = KS_FALSE;
}
//while (ks_q_trypop(bc->sending, (void **)&message) == KS_STATUS_SUCCESS && message) blade_message_discard(&message);
//while (ks_q_trypop(bc->receiving, (void **)&message) == KS_STATUS_SUCCESS && message) blade_message_discard(&message);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->transport_data;
}
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state)
{
ks_assert(bc);
bc->transport_callbacks->onstate(bc, state, BLADE_CONNECTION_STATE_CONDITION_PRE);
bc->state = state;
}
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc)
{
ks_assert(bc);
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_DISCONNECT);
}
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, blade_identity_t *target, cJSON *json)
{
ks_assert(bc);
ks_assert(json);
// @todo need internal envelope to wrap an identity object and a json object just for the queue
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, blade_identity_t **target, cJSON **json)
{
ks_assert(bc);
ks_assert(json);
// @todo need internal envelope to wrap an identity object and a json object just for the queue
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_receiving_push(blade_connection_t *bc, cJSON *json)
{
ks_assert(bc);
ks_assert(json);
return ks_q_push(bc->receiving, json);
}
KS_DECLARE(ks_status_t) blade_connection_receiving_pop(blade_connection_t *bc, cJSON **json)
{
ks_assert(bc);
ks_assert(json);
return ks_q_trypop(bc->receiving, (void **)json);
}
void *blade_connection_state_thread(ks_thread_t *thread, void *data)
{
blade_connection_t *bc = NULL;
blade_connection_state_hook_t hook;
ks_assert(thread);
ks_assert(data);
bc = (blade_connection_t *)data;
while (!bc->shutdown) {
// @todo need to get messages from the transport into receiving queue, and pop messages from sending queue to write out using transport
// sending is relatively easy, but receiving cannot occur universally due to cases like kws_init() blocking and expecting data to be on the wire
// and other transports may have similar behaviours, but CONNECTIN, ATTACH, and READY require async message passing into application layer
// and sending whenever the response hits the queue
// @todo it's possible that onstate could handle receiving and sending messages during the appropriate states, but this means some states
// like CONNECTIN which may send and receive multiple messages require BYPASSing until the application layer updates the state or disconnects
hook = bc->transport_callbacks->onstate(bc, bc->state, BLADE_CONNECTION_STATE_CONDITION_POST);
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT)
blade_connection_disconnect(bc);
else if (hook == BLADE_CONNECTION_STATE_HOOK_SUCCESS) {
// @todo pop from sending queue, and pass to transport callback to send out
switch (bc->state) {
case BLADE_CONNECTION_STATE_NEW:
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_CONNECT);
break;
case BLADE_CONNECTION_STATE_CONNECT:
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_ATTACH);
break;
case BLADE_CONNECTION_STATE_ATTACH:
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_READY);
break;
case BLADE_CONNECTION_STATE_DETACH:
blade_connection_disconnect(bc);
break;
default: break;
}
}
}
return NULL;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_identity_s {
ks_pool_t *pool;
const char *uri;
// @todo breakdown of uri into constituent parts
};
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool)
{
blade_identity_t *bi = NULL;
ks_assert(biP);
ks_assert(pool);
bi = ks_pool_alloc(pool, sizeof(blade_identity_t));
bi->pool = pool;
*biP = bi;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP)
{
blade_identity_t *bi = NULL;
ks_assert(biP);
ks_assert(*biP);
bi = *biP;
ks_pool_free(bi->pool, biP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri)
{
ks_assert(bi);
ks_assert(uri);
if (bi->uri) ks_pool_free(bi->pool, &bi->uri);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_identity_uri(blade_identity_t *bi, const char **uri)
{
ks_assert(bi);
ks_assert(uri);
*uri = bi->uri;
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_module_s {
blade_handle_t *handle;
ks_pool_t *pool;
void *module_data;
blade_module_callbacks_t *module_callbacks;
};
KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, void *module_data, blade_module_callbacks_t *module_callbacks)
{
blade_module_t *bm = NULL;
ks_pool_t *pool = NULL;
ks_assert(bmP);
ks_assert(bh);
ks_assert(module_data);
ks_assert(module_callbacks);
pool = blade_handle_pool_get(bh);
bm = ks_pool_alloc(pool, sizeof(blade_module_t));
bm->handle = bh;
bm->pool = pool;
bm->module_data = module_data;
bm->module_callbacks = module_callbacks;
*bmP = bm;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP)
{
blade_module_t *bm = NULL;
ks_assert(bmP);
ks_assert(*bmP);
bm = *bmP;
ks_pool_free(bm->pool, bmP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm)
{
ks_assert(bm);
return bm->module_data;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
差异被折叠。
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_peer_s {
ks_pool_t *pool;
ks_thread_pool_t *tpool;
blade_service_t *service;
ks_socket_t sock;
ks_bool_t shutdown;
blade_peerstate_t state;
blade_peerreason_t reason;
kws_t *kws;
ks_thread_t *kws_thread;
ks_q_t *messages_sending;
ks_q_t *messages_receiving;
};
void *blade_peer_kws_thread(ks_thread_t *thread, void *data);
KS_DECLARE(ks_status_t) blade_peer_destroy(blade_peer_t **bpP)
{
blade_peer_t *bp = NULL;
ks_assert(bpP);
bp = *bpP;
*bpP = NULL;
ks_assert(bp);
blade_peer_shutdown(bp);
ks_q_destroy(&bp->messages_sending);
ks_q_destroy(&bp->messages_receiving);
ks_pool_free(bp->pool, &bp);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_peer_create(blade_peer_t **bpP, ks_pool_t *pool, ks_thread_pool_t *tpool, blade_service_t *service)
{
blade_peer_t *bp = NULL;
ks_assert(bpP);
ks_assert(pool);
ks_assert(tpool);
ks_assert(service);
bp = ks_pool_alloc(pool, sizeof(*bp));
bp->pool = pool;
bp->tpool = tpool;
bp->service = service;
bp->state = BLADE_PEERSTATE_CONNECTING;
bp->reason = BLADE_PEERREASON_NORMAL;
ks_q_create(&bp->messages_sending, pool, 0);
ks_q_create(&bp->messages_receiving, pool, 0);
*bpP = bp;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_peer_startup(blade_peer_t *bp, ks_socket_t sock)
{
kws_t *kws = NULL;
ks_assert(bp);
ks_assert(kws);
// @todo: consider using a recycle queue for blade_peer_t in blade_service_t, just need to call startup then
blade_peer_shutdown(bp);
bp->sock = sock;
bp->state = BLADE_PEERSTATE_CONNECTING;
bp->reason = BLADE_PEERREASON_NORMAL;
if (ks_thread_create_ex(&bp->kws_thread,
blade_peer_kws_thread,
bp,
KS_THREAD_FLAG_DEFAULT,
KS_THREAD_DEFAULT_STACK,
KS_PRI_NORMAL,
bp->pool) != KS_STATUS_SUCCESS) {
// @todo error logging
blade_peer_disconnect(bp, BLADE_PEERREASON_ERROR);
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_peer_shutdown(blade_peer_t *bp)
{
blade_message_t *message = NULL;
ks_assert(bp);
bp->shutdown = KS_TRUE;
if (bp->kws_thread) {
ks_thread_join(bp->kws_thread);
ks_pool_free(bp->pool, &bp->kws_thread);
}
while (ks_q_trypop(bp->messages_sending, (void **)&message) == KS_STATUS_SUCCESS && message) blade_message_discard(&message);
while (ks_q_trypop(bp->messages_receiving, (void **)&message) == KS_STATUS_SUCCESS && message) blade_message_discard(&message);
if (bp->kws) kws_destroy(&bp->kws);
else if (bp->sock != KS_SOCK_INVALID) ks_socket_close(&bp->sock);
bp->sock = KS_SOCK_INVALID;
bp->shutdown = KS_FALSE;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(void) blade_peer_disconnect(blade_peer_t *bp, blade_peerreason_t reason)
{
ks_assert(bp);
// @todo check if already disconnecting for another reason, avoid resetting to get initial reason for disconnect?
bp->reason = reason;
bp->state = BLADE_PEERSTATE_DISCONNECTING;
}
KS_DECLARE(blade_peerstate_t) blade_peer_state(blade_peer_t *bp)
{
ks_assert(bp);
return bp->state;
}
KS_DECLARE(ks_status_t) blade_peer_message_pop(blade_peer_t *peer, blade_message_t **message)
{
ks_assert(peer);
ks_assert(message);
*message = NULL;
return ks_q_trypop(peer->messages_receiving, (void **)message);
}
KS_DECLARE(ks_status_t) blade_peer_message_push(blade_peer_t *peer, void *data, ks_size_t data_length)
{
blade_message_t *message = NULL;
ks_assert(peer);
ks_assert(data);
ks_assert(data_length > 0);
if (blade_handle_message_claim(blade_service_handle(peer->service), &message, data, data_length) != KS_STATUS_SUCCESS || !message) {
// @todo error logging
blade_peer_disconnect(peer, BLADE_PEERREASON_ERROR);
return KS_STATUS_FAIL;
}
ks_q_push(peer->messages_sending, message);
return KS_STATUS_SUCCESS;
}
void *blade_peer_kws_thread(ks_thread_t *thread, void *data)
{
blade_peer_t *peer = NULL;
kws_opcode_t opcode;
uint8_t *frame_data = NULL;
ks_size_t frame_data_len = 0;
blade_message_t *message = NULL;
int32_t poll_flags = 0;
ks_assert(thread);
ks_assert(data);
peer = (blade_peer_t *)data;
// @todo consider using an INITIALIZING state to track when there is problems during initialization (specifically SSL negotiations)?
// @todo should stack be notified with an internal event callback here before logic layer initialization starts (IE, before SSL negotiations)?
peer->state = BLADE_PEERSTATE_RUNNING;
// @todo: SSL init stuffs based on data from peer->service->config_websockets_ssl to pass into kws_init
if (kws_init(&peer->kws, peer->sock, NULL, NULL, KWS_BLOCK, peer->pool) != KS_STATUS_SUCCESS) {
// @todo error logging
blade_peer_disconnect(peer, BLADE_PEERREASON_ERROR);
return NULL;
}
blade_service_peer_state_callback(peer->service, peer, BLADE_PEERSTATE_RUNNING);
while (!peer->shutdown) {
// @todo get exact timeout from service config?
poll_flags = ks_wait_sock(peer->sock, 100, KS_POLL_READ | KS_POLL_ERROR);
if (poll_flags & KS_POLL_ERROR) {
// @todo error logging
blade_peer_disconnect(peer, BLADE_PEERREASON_ERROR);
break;
}
if (poll_flags & KS_POLL_READ) {
frame_data_len = kws_read_frame(peer->kws, &opcode, &frame_data);
if (frame_data_len <= 0) {
// @todo error logging, strerror(ks_errno())
// 0 means socket closed with WS_NONE, which closes websocket with no additional reason
// -1 means socket closed with a general failure
// -2 means nonblocking wait
// other values are based on WS_XXX reasons
// negative values are based on reasons, except for -1 is but -2 is nonblocking wait, and
blade_peer_disconnect(peer, BLADE_PEERREASON_ERROR);
break;
}
if (blade_handle_message_claim(blade_service_handle(peer->service), &message, frame_data, frame_data_len) != KS_STATUS_SUCCESS || !message) {
// @todo error logging
blade_peer_disconnect(peer, BLADE_PEERREASON_ERROR);
break;
}
ks_q_push(peer->messages_receiving, message);
blade_service_peer_state_callback(peer->service, peer, BLADE_PEERSTATE_RECEIVING);
}
// @todo consider only sending one message at a time and use shorter polling timeout to prevent any considerable blocking if send buffers get full
while (ks_q_trypop(peer->messages_sending, (void **)&message) == KS_STATUS_SUCCESS && message) {
blade_message_get(message, (void **)&frame_data, &frame_data_len);
// @todo may need to get the WSOC_TEXT from the message if using WSOC_BINARY is desired later
kws_write_frame(peer->kws, WSOC_TEXT, frame_data, frame_data_len);
}
}
return NULL;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
差异被折叠。
......@@ -48,7 +48,6 @@ struct blade_handle_s {
config_setting_t *config_datastore;
ks_q_t *messages_discarded;
blade_service_t *service;
blade_datastore_t *datastore;
};
......@@ -143,7 +142,7 @@ ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config, blade_service_peer_state_callback_t service_peer_state_callback)
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config)
{
ks_assert(bh);
......@@ -152,15 +151,6 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_
return KS_STATUS_FAIL;
}
if (bh->config_service && !blade_handle_service_available(bh)) {
blade_service_create(&bh->service, bh->pool, bh->tpool, bh, service_peer_state_callback);
ks_assert(bh->service);
if (blade_service_startup(bh->service, bh->config_service) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_service_startup failed\n");
return KS_STATUS_FAIL;
}
}
if (bh->config_datastore && !blade_handle_datastore_available(bh)) {
blade_datastore_create(&bh->datastore, bh->pool, bh->tpool);
ks_assert(bh->datastore);
......@@ -177,13 +167,23 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
{
ks_assert(bh);
if (blade_handle_service_available(bh)) blade_service_destroy(&bh->service);
if (blade_handle_datastore_available(bh)) blade_datastore_destroy(&bh->datastore);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_pool_t *) blade_handle_pool_get(blade_handle_t *bh)
{
ks_assert(bh);
return bh->pool;
}
KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh)
{
ks_assert(bh);
return bh->tpool;
}
KS_DECLARE(ks_status_t) blade_handle_message_claim(blade_handle_t *bh, blade_message_t **message, void *data, ks_size_t data_length)
{
blade_message_t *msg = NULL;
......@@ -218,12 +218,7 @@ KS_DECLARE(ks_status_t) blade_handle_message_discard(blade_handle_t *bh, blade_m
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_handle_service_available(blade_handle_t *bh)
{
ks_assert(bh);
return bh->service != NULL;
}
KS_DECLARE(ks_bool_t) blade_handle_datastore_available(blade_handle_t *bh)
{
......
......@@ -40,12 +40,14 @@
#include "unqlite.h"
#include "blade_types.h"
#include "blade_stack.h"
#include "blade_peer.h"
#include "blade_service.h"
#include "blade_message.h"
#include "blade_datastore.h"
#include "bpcp.h"
#include "blade_identity.h"
#include "blade_module.h"
#include "blade_connection.h"
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_init(void);
......
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_CONNECTION_H_
#define _BLADE_CONNECTION_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP,
blade_handle_t *bh,
void *transport_data,
blade_transport_callbacks_t *transport_callbacks);
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP);
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc);
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc);
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc);
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state);
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc);
KS_DECLARE(blade_connection_rank_t) blade_connection_rank(blade_connection_t *bc, blade_identity_t *target);
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, blade_identity_t *target, cJSON *json);
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, blade_identity_t **target, cJSON **json);
KS_DECLARE(ks_status_t) blade_connection_receiving_push(blade_connection_t *bc, cJSON *json);
KS_DECLARE(ks_status_t) blade_connection_receiving_pop(blade_connection_t *bc, cJSON **json);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -31,21 +31,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_SERVICE_H_
#define _BLADE_SERVICE_H_
#ifndef _BLADE_IDENTITY_H_
#define _BLADE_IDENTITY_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_service_create(blade_service_t **bsP,
ks_pool_t *pool,
ks_thread_pool_t *tpool,
blade_handle_t *handle,
blade_service_peer_state_callback_t peer_state_callback);
KS_DECLARE(ks_status_t) blade_service_destroy(blade_service_t **bsP);
KS_DECLARE(blade_handle_t *) blade_service_handle(blade_service_t *bs);
KS_DECLARE(ks_status_t) blade_service_startup(blade_service_t *bs, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_service_shutdown(blade_service_t *bs);
KS_DECLARE(void) blade_service_peer_state_callback(blade_service_t *bs, blade_peer_t *bp, blade_peerstate_t state);
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool);
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP);
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri);
KS_DECLARE(ks_status_t) blade_identity_uri(blade_identity_t *bi, const char **uri);
KS_END_EXTERN_C
#endif
......
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -31,20 +31,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_PEER_H_
#define _BLADE_PEER_H_
#ifndef _BLADE_MODULE_H_
#define _BLADE_MODULE_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_peer_create(blade_peer_t **bpP, ks_pool_t *pool, ks_thread_pool_t *tpool, blade_service_t *service);
KS_DECLARE(ks_status_t) blade_peer_destroy(blade_peer_t **bpP);
KS_DECLARE(ks_status_t) blade_peer_startup(blade_peer_t *bp, ks_socket_t sock);
KS_DECLARE(ks_status_t) blade_peer_shutdown(blade_peer_t *bp);
KS_DECLARE(void) blade_peer_disconnect(blade_peer_t *bp, blade_peerreason_t reason);
KS_DECLARE(blade_peerstate_t) blade_peer_state(blade_peer_t *bp);
KS_DECLARE(blade_peerreason_t) blade_peer_reason(blade_peer_t *bp);
KS_DECLARE(ks_status_t) blade_peer_message_pop(blade_peer_t *peer, blade_message_t **message);
KS_DECLARE(ks_status_t) blade_peer_message_push(blade_peer_t *peer, void *data, ks_size_t data_length);
KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, void *module_data, blade_module_callbacks_t *module_callbacks);
KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP);
KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm);
KS_END_EXTERN_C
#endif
......
......@@ -43,14 +43,14 @@
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP);
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool);
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config, blade_service_peer_state_callback_t service_peer_state_callback);
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh);
KS_DECLARE(ks_pool_t *) blade_handle_pool_get(blade_handle_t *bh);
KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_handle_message_claim(blade_handle_t *bh, blade_message_t **message, void *data, ks_size_t data_length);
KS_DECLARE(ks_status_t) blade_handle_message_discard(blade_handle_t *bh, blade_message_t **message);
KS_DECLARE(ks_bool_t) blade_handle_service_available(blade_handle_t *bh);
KS_DECLARE(ks_bool_t) blade_handle_datastore_available(blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const void *key, int32_t key_length, const void *data, int64_t data_length);
KS_DECLARE(ks_status_t) blade_handle_datastore_fetch(blade_handle_t *bh,
......
......@@ -37,28 +37,79 @@
KS_BEGIN_EXTERN_C
typedef enum {
BLADE_PEERSTATE_CONNECTING,
BLADE_PEERSTATE_DISCONNECTING,
BLADE_PEERSTATE_RUNNING,
BLADE_PEERSTATE_RECEIVING,
} blade_peerstate_t;
typedef enum {
BLADE_PEERREASON_NORMAL,
BLADE_PEERREASON_ERROR,
// @todo populate more reasons for disconnecting as neccessary
} blade_peerreason_t;
typedef struct blade_handle_s blade_handle_t;
typedef struct blade_peer_s blade_peer_t;
typedef struct blade_service_s blade_service_t;
typedef struct blade_identity_s blade_identity_t;
typedef struct blade_module_s blade_module_t;
typedef struct blade_module_callbacks_s blade_module_callbacks_t;
typedef struct blade_transport_callbacks_s blade_transport_callbacks_t;
typedef struct blade_connection_s blade_connection_t;
typedef struct blade_message_s blade_message_t;
typedef struct blade_datastore_s blade_datastore_t;
typedef void (*blade_service_peer_state_callback_t)(blade_service_t *bs, blade_peer_t *bp, blade_peerstate_t state);
typedef ks_bool_t (*blade_datastore_fetch_callback_t)(blade_datastore_t *bds, const void *data, uint32_t data_length, void *userdata);
typedef enum {
BLADE_CONNECTION_STATE_NONE,
BLADE_CONNECTION_STATE_DISCONNECT,
BLADE_CONNECTION_STATE_NEW,
BLADE_CONNECTION_STATE_CONNECT,
BLADE_CONNECTION_STATE_ATTACH,
BLADE_CONNECTION_STATE_DETACH,
BLADE_CONNECTION_STATE_READY,
} blade_connection_state_t;
typedef enum {
BLADE_CONNECTION_DIRECTION_IN,
BLADE_CONNECTION_DIRECTION_OUT,
} blade_connection_direction_t;
typedef enum {
BLADE_CONNECTION_STATE_CONDITION_PRE,
BLADE_CONNECTION_STATE_CONDITION_POST,
} blade_connection_state_condition_t;
typedef enum {
BLADE_CONNECTION_STATE_HOOK_SUCCESS,
BLADE_CONNECTION_STATE_HOOK_DISCONNECT,
BLADE_CONNECTION_STATE_HOOK_BYPASS,
} blade_connection_state_hook_t;
typedef enum {
BLADE_CONNECTION_RANK_POOR,
BLADE_CONNECTION_RANK_AVERAGE,
BLADE_CONNECTION_RANK_GOOD,
BLADE_CONNECTION_RANK_GREAT,
} blade_connection_rank_t;
typedef ks_status_t (*blade_module_load_callback_t)(blade_module_t **bmP, blade_handle_t *bh);
typedef ks_status_t (*blade_module_unload_callback_t)(blade_module_t *bm);
typedef ks_status_t (*blade_module_startup_callback_t)(blade_module_t *bm, config_setting_t *config);
typedef ks_status_t (*blade_module_shutdown_callback_t)(blade_module_t *bm);
struct blade_module_callbacks_s {
blade_module_load_callback_t onload;
blade_module_unload_callback_t onunload;
blade_module_startup_callback_t onstartup;
blade_module_shutdown_callback_t onshutdown;
};
typedef ks_status_t (*blade_transport_connect_callback_t)(blade_connection_t **bcP, blade_module_t *bm, blade_identity_t *target);
typedef blade_connection_rank_t (*blade_transport_rank_callback_t)(blade_connection_t *bc, blade_identity_t *target);
typedef blade_connection_state_hook_t (*blade_transport_state_callback_t)(blade_connection_t *bc,
blade_connection_state_t state,
blade_connection_state_condition_t condition);
struct blade_transport_callbacks_s {
blade_transport_connect_callback_t onconnect;
blade_transport_rank_callback_t onrank;
blade_transport_state_callback_t onstate;
};
KS_END_EXTERN_C
#endif
......
#! /bin/bash
# bladec - temporary wrapper script for .libs/bladec
# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.11
#
# The bladec program cannot be directly executed until all the libtool
# libraries that it depends on are installed.
#
# This wrapper script should never be moved out of the build directory.
# If it is, it will not operate correctly.
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
fi
BIN_SH=xpg4; export BIN_SH # for Tru64
DUALCASE=1; export DUALCASE # for MKS sh
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
relink_command="(cd /usr/src/freeswitch/libs/libblade/test; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/lib/ccache:/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin; export PATH; gcc -fPIC -Wall -std=c99 -pedantic -DUSE_SCHED_SETSCHEDULER=1 -DKS_API_VISIBILITY=1 -fvisibility=hidden -Werror -DHAVE_PTHREAD_SETSCHEDPARAM=1 -DHAVE_OPENSSL -fsanitize=address -fno-omit-frame-pointer -I/usr/src/freeswitch/libs/libblade/src/include -g -ggdb -O0 -g -O2 -fsanitize=address -o \$progdir/\$file bladec-bladec.o bladec-tap.o -L/usr/src/freeswitch/libs/libblade/../libks/.libs/ /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.so -lsodium /usr/src/freeswitch/libs/libblade/.libs/libblade.so -lconfig -lm -lpthread -lssl -lcrypto -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/../libks/.libs/ -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/.libs)"
# This environment variable determines our operation mode.
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
# install mode needs the following variables:
generated_by_libtool_version='2.4.2'
notinst_deplibs=' /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.la /usr/src/freeswitch/libs/libblade/libblade.la'
else
# When we are sourced in execute mode, $file and $ECHO are already set.
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
file="$0"
# A function that is used when there is no print builtin or printf.
func_fallback_echo ()
{
eval 'cat <<_LTECHO_EOF
$1
_LTECHO_EOF'
}
ECHO="printf %s\\n"
fi
# Very basic option parsing. These options are (a) specific to
# the libtool wrapper, (b) are identical between the wrapper
# /script/ and the wrapper /executable/ which is used only on
# windows platforms, and (c) all begin with the string --lt-
# (application programs are unlikely to have options which match
# this pattern).
#
# There are only two supported options: --lt-debug and
# --lt-dump-script. There is, deliberately, no --lt-help.
#
# The first argument to this parsing function should be the
# script's ../libtool value, followed by no.
lt_option_debug=
func_parse_lt_options ()
{
lt_script_arg0=$0
shift
for lt_opt
do
case "$lt_opt" in
--lt-debug) lt_option_debug=1 ;;
--lt-dump-script)
lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
cat "$lt_dump_D/$lt_dump_F"
exit 0
;;
--lt-*)
$ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
exit 1
;;
esac
done
# Print the debug banner immediately:
if test -n "$lt_option_debug"; then
echo "bladec:bladec:${LINENO}: libtool wrapper (GNU libtool) 2.4.2 Debian-2.4.2-1.11" 1>&2
fi
}
# Used when --lt-debug. Prints its arguments to stdout
# (redirection is the responsibility of the caller)
func_lt_dump_args ()
{
lt_dump_args_N=1;
for lt_arg
do
$ECHO "bladec:bladec:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
lt_dump_args_N=`expr $lt_dump_args_N + 1`
done
}
# Core function for launching the target application
func_exec_program_core ()
{
if test -n "$lt_option_debug"; then
$ECHO "bladec:bladec:${LINENO}: newargv[0]: $progdir/$program" 1>&2
func_lt_dump_args ${1+"$@"} 1>&2
fi
exec "$progdir/$program" ${1+"$@"}
$ECHO "$0: cannot exec $program $*" 1>&2
exit 1
}
# A function to encapsulate launching the target application
# Strips options in the --lt-* namespace from $@ and
# launches target application with the remaining arguments.
func_exec_program ()
{
case " $* " in
*\ --lt-*)
for lt_wr_arg
do
case $lt_wr_arg in
--lt-*) ;;
*) set x "$@" "$lt_wr_arg"; shift;;
esac
shift
done ;;
esac
func_exec_program_core ${1+"$@"}
}
# Parse options
func_parse_lt_options "$0" ${1+"$@"}
# Find the directory that this script lives in.
thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
test "x$thisdir" = "x$file" && thisdir=.
# Follow symbolic links until we get to the real thisdir.
file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
while test -n "$file"; do
destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
# If there was a directory component, then change thisdir.
if test "x$destdir" != "x$file"; then
case "$destdir" in
[\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
*) thisdir="$thisdir/$destdir" ;;
esac
fi
file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
done
# Usually 'no', except on cygwin/mingw when embedded into
# the cwrapper.
WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
# special case for '.'
if test "$thisdir" = "."; then
thisdir=`pwd`
fi
# remove .libs from thisdir
case "$thisdir" in
*[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
.libs ) thisdir=. ;;
esac
fi
# Try to get the absolute directory name.
absdir=`cd "$thisdir" && pwd`
test -n "$absdir" && thisdir="$absdir"
program=lt-'bladec'
progdir="$thisdir/.libs"
if test ! -f "$progdir/$program" ||
{ file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
test "X$file" != "X$progdir/$program"; }; then
file="$$-$program"
if test ! -d "$progdir"; then
mkdir "$progdir"
else
rm -f "$progdir/$file"
fi
# relink executable if necessary
if test -n "$relink_command"; then
if relink_command_output=`eval $relink_command 2>&1`; then :
else
printf %s\n "$relink_command_output" >&2
rm -f "$progdir/$file"
exit 1
fi
fi
mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
{ rm -f "$progdir/$program";
mv -f "$progdir/$file" "$progdir/$program"; }
rm -f "$progdir/$file"
fi
if test -f "$progdir/$program"; then
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
# Run the actual program with our arguments.
func_exec_program ${1+"$@"}
fi
else
# The program doesn't exist.
$ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
$ECHO "This script is just a wrapper for $program." 1>&2
$ECHO "See the libtool documentation for more information." 1>&2
exit 1
fi
fi
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论