summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2015-05-01 16:35:43 +0900
committerSung-jae Park <nicesj.park@samsung.com>2015-05-01 16:41:57 +0900
commitd897d062c40bdad08fd387ce3d5504de79e8f29a (patch)
tree0df91e9c2cab160305bffbe6f42b5fcb5a15977c
parent218dd748ed5405c4c0fcd2728b9841162956ef3d (diff)
downloadcom-core-d897d062c40bdad08fd387ce3d5504de79e8f29a.tar.gz
com-core-d897d062c40bdad08fd387ce3d5504de79e8f29a.tar.bz2
com-core-d897d062c40bdad08fd387ce3d5504de79e8f29a.zip
Sync with the latest 2.3.1
[model] Redwood,Kiran,B3(Wearable) [binary_type] AP [customer] Docomo/Orange/ATT/Open [issue#] N/A [problem] [cause] [solution] [team] HomeTF [request] [horizontal_expansion] Change-Id: I46bb8c0de37684f42ce59511816a7149cc7ab9b5
-rw-r--r--include/com-core.h2
-rw-r--r--include/com-core_packet.h12
-rw-r--r--include/com-core_thread.h2
-rw-r--r--include/secure_socket.h12
-rw-r--r--packaging/libcom-core.spec3
-rw-r--r--src/com-core.c1040
-rw-r--r--src/com-core_packet-router.c19
-rw-r--r--src/com-core_packet.c1223
-rw-r--r--src/com-core_thread.c1454
-rw-r--r--src/dlist.c2
-rw-r--r--src/packet.c872
-rw-r--r--src/secure_socket.c826
12 files changed, 2767 insertions, 2700 deletions
diff --git a/include/com-core.h b/include/com-core.h
index 16d743c..4c9ba0e 100644
--- a/include/com-core.h
+++ b/include/com-core.h
@@ -39,7 +39,7 @@ enum com_core_event_type {
* \retval
* \sa
*/
-extern int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
+extern int com_core_server_create(const char *addr, int is_sync, const char *label, int (*service_cb)(int fd, void *data), void *data);
/*!
* \brief
diff --git a/include/com-core_packet.h b/include/com-core_packet.h
index 2e19b9f..9ed9990 100644
--- a/include/com-core_packet.h
+++ b/include/com-core_packet.h
@@ -107,6 +107,18 @@ extern int com_core_packet_server_init(const char *addr, struct method *table);
* \brief
* \details N/A
* \remarks N/A
+ * \param[in] addr
+ * \param[in] table
+ * \return int
+ * \retval
+ * \sa
+ */
+extern int com_core_packet_server_init_with_permission(const char *addr, struct method *table, const char *label);
+
+/*!
+ * \brief
+ * \details N/A
+ * \remarks N/A
* \param[in] handle
* \return int
* \retval
diff --git a/include/com-core_thread.h b/include/com-core_thread.h
index a2463a2..6d9eae1 100644
--- a/include/com-core_thread.h
+++ b/include/com-core_thread.h
@@ -23,7 +23,7 @@ extern "C" {
#endif
extern int com_core_thread_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
-extern int com_core_thread_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
+extern int com_core_thread_server_create(const char *addr, int is_sync, const char *label, int (*service_cb)(int fd, void *data), void *data);
extern int com_core_thread_server_destroy(int handle);
extern int com_core_thread_client_destroy(int handle);
diff --git a/include/secure_socket.h b/include/secure_socket.h
index 64f1aca..4db3331 100644
--- a/include/secure_socket.h
+++ b/include/secure_socket.h
@@ -64,6 +64,18 @@ extern int secure_socket_create_client(const char *peer);
extern int secure_socket_create_server(const char *peer);
/*!
+ * \brief Create server connection
+ * \details N/A
+ * \remarks N/A
+ * \param[in] peer
+ * \return int
+ * \retval
+ * \sa
+ */
+extern int secure_socket_create_server_with_permission(const char *peer, const char *label);
+
+
+/*!
* \brief Get the raw handle to use it for non-blocking mode.
* \details N/A
* \remarks N/A
diff --git a/packaging/libcom-core.spec b/packaging/libcom-core.spec
index e20f156..d970f43 100644
--- a/packaging/libcom-core.spec
+++ b/packaging/libcom-core.spec
@@ -1,12 +1,13 @@
Name: libcom-core
Summary: Library for the light-weight IPC
-Version: 0.7.0
+Version: 1.0.0
Release: 1
Group: Base/IPC
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
Source1001: %{name}.manifest
BuildRequires: cmake, gettext-tools, coreutils
+BuildRequires: libattr-devel
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libsystemd-daemon)
diff --git a/src/com-core.c b/src/com-core.c
index ceec3a7..23ec955 100644
--- a/src/com-core.c
+++ b/src/com-core.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#include <stdio.h>
#include <errno.h>
@@ -37,657 +37,657 @@
#include "util.h"
static struct {
- struct dlist *watch_list;
- struct dlist *conn_cb_list;
- struct dlist *disconn_cb_list;
- enum processing_event_callback {
- PROCESSING_NONE = 0x0,
- PROCESSING_DISCONNECTION = 0x01,
- PROCESSING_CONNECTION = 0x02,
- } processing_event_callback;
+ struct dlist *watch_list;
+ struct dlist *conn_cb_list;
+ struct dlist *disconn_cb_list;
+ enum processing_event_callback {
+ PROCESSING_NONE = 0x0,
+ PROCESSING_DISCONNECTION = 0x01,
+ PROCESSING_CONNECTION = 0x02,
+ } processing_event_callback;
} s_info = {
- .watch_list = NULL,
- .conn_cb_list = NULL,
- .disconn_cb_list = NULL,
- .processing_event_callback = PROCESSING_NONE,
+ .watch_list = NULL,
+ .conn_cb_list = NULL,
+ .disconn_cb_list = NULL,
+ .processing_event_callback = PROCESSING_NONE,
};
struct watch_item {
- int server_fd;
- int fd;
- guint id;
- void *cbdata;
+ int server_fd;
+ int fd;
+ guint id;
+ void *cbdata;
};
struct cbdata {
- int (*service_cb)(int fd, void *data);
- void *data;
+ int (*service_cb)(int fd, void *data);
+ void *data;
};
struct evtdata {
- int deleted;
- int (*evt_cb)(int fd, void *data);
- void *data;
+ int deleted;
+ int (*evt_cb)(int fd, void *data);
+ void *data;
};
static int watch_item_create(int server_fd, int handle, guint id, void *cbdata)
{
- struct watch_item *item;
+ struct watch_item *item;
- item = malloc(sizeof(*item));
- if (!item) {
- return -ENOMEM;
- }
+ item = malloc(sizeof(*item));
+ if (!item) {
+ return -ENOMEM;
+ }
- item->server_fd = server_fd;
- item->fd = handle;
- item->id = id;
- item->cbdata = cbdata;
+ item->server_fd = server_fd;
+ item->fd = handle;
+ item->id = id;
+ item->cbdata = cbdata;
- DbgPrint("Watch Item is created for %d/%d\n", server_fd, handle);
- s_info.watch_list = dlist_append(s_info.watch_list, item);
- return 0;
+ DbgPrint("Watch Item is created for %d/%d\n", server_fd, handle);
+ s_info.watch_list = dlist_append(s_info.watch_list, item);
+ return 0;
}
static int watch_item_destroy(int handle, int remove_id, int remove_cbdata)
{
- struct dlist *l;
- struct dlist *n;
- struct watch_item *item;
+ struct dlist *l;
+ struct dlist *n;
+ struct watch_item *item;
- dlist_foreach_safe(s_info.watch_list, l, n, item) {
- if (item->fd == handle) {
- s_info.watch_list = dlist_remove(s_info.watch_list, l);
+ dlist_foreach_safe(s_info.watch_list, l, n, item) {
+ if (item->fd == handle) {
+ s_info.watch_list = dlist_remove(s_info.watch_list, l);
- DbgPrint("Watch item is destroyed for %d/%d\n", item->server_fd, item->fd);
+ DbgPrint("Watch item is destroyed for %d/%d\n", item->server_fd, item->fd);
- if (remove_id && item->id) {
- g_source_remove(item->id);
- }
+ if (remove_id && item->id) {
+ g_source_remove(item->id);
+ }
- if (remove_cbdata && item->cbdata) {
- free(item->cbdata);
- }
+ if (remove_cbdata && item->cbdata) {
+ free(item->cbdata);
+ }
- free(item);
- return 0;
+ free(item);
+ return 0;
+ }
}
- }
- DbgPrint("No entry found\n");
- return -ENOENT;
+ DbgPrint("No entry found\n");
+ return -ENOENT;
}
static void watch_item_destroy_all(int socket_fd)
{
- struct dlist *l;
- struct dlist *n;
- struct watch_item *item;
-
- dlist_foreach_safe(s_info.watch_list, l, n, item) {
- if (item->server_fd == socket_fd) {
- DbgPrint("Watch item removed: %d/%d\n", item->server_fd, item->fd);
- /*!
- * \WARN
- * If the watch_list item is removed from disconnected
- * callback, this list loop can be broken.
- * Please check it again.
- */
- invoke_disconn_cb_list(item->fd, 0, 0, 0);
-
- s_info.watch_list = dlist_remove(s_info.watch_list, l);
- if (item->id > 0) {
- g_source_remove(item->id);
- }
- free(item->cbdata);
- free(item);
- }
- }
+ struct dlist *l;
+ struct dlist *n;
+ struct watch_item *item;
+
+ dlist_foreach_safe(s_info.watch_list, l, n, item) {
+ if (item->server_fd == socket_fd) {
+ DbgPrint("Watch item removed: %d/%d\n", item->server_fd, item->fd);
+ /*!
+ * \WARN
+ * If the watch_list item is removed from disconnected
+ * callback, this list loop can be broken.
+ * Please check it again.
+ */
+ invoke_disconn_cb_list(item->fd, 0, 0, 0);
+
+ s_info.watch_list = dlist_remove(s_info.watch_list, l);
+ if (item->id > 0) {
+ g_source_remove(item->id);
+ }
+ free(item->cbdata);
+ free(item);
+ }
+ }
}
HAPI void invoke_con_cb_list(int server_fd, int handle, guint id, void *data, int watch)
{
- struct dlist *l;
- struct dlist *n;
- struct evtdata *cbdata;
-
- if (watch) {
- if (watch_item_create(server_fd, handle, id, data) < 0) {
- ErrPrint("Failed to create a watch item\n");
- }
- }
-
- s_info.processing_event_callback |= PROCESSING_CONNECTION;
- dlist_foreach_safe(s_info.conn_cb_list, l, n, cbdata) {
- /*!
- * \NOTE
- * cbdata->deleted must has to be checked before call the function and
- * return from the function call.
- */
- if (cbdata->deleted || cbdata->evt_cb(handle, cbdata->data) < 0 || cbdata->deleted) {
- s_info.conn_cb_list = dlist_remove(s_info.conn_cb_list, l);
- free(cbdata);
- }
- }
- s_info.processing_event_callback &= ~PROCESSING_CONNECTION;
+ struct dlist *l;
+ struct dlist *n;
+ struct evtdata *cbdata;
+
+ if (watch) {
+ if (watch_item_create(server_fd, handle, id, data) < 0) {
+ ErrPrint("Failed to create a watch item\n");
+ }
+ }
+
+ s_info.processing_event_callback |= PROCESSING_CONNECTION;
+ dlist_foreach_safe(s_info.conn_cb_list, l, n, cbdata) {
+ /*!
+ * \NOTE
+ * cbdata->deleted must has to be checked before call the function and
+ * return from the function call.
+ */
+ if (cbdata->deleted || cbdata->evt_cb(handle, cbdata->data) < 0 || cbdata->deleted) {
+ s_info.conn_cb_list = dlist_remove(s_info.conn_cb_list, l);
+ free(cbdata);
+ }
+ }
+ s_info.processing_event_callback &= ~PROCESSING_CONNECTION;
}
HAPI void invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int watch)
{
- struct dlist *l;
- struct dlist *n;
- struct evtdata *cbdata;
-
- s_info.processing_event_callback |= PROCESSING_DISCONNECTION;
- dlist_foreach_safe(s_info.disconn_cb_list, l, n, cbdata) {
- /*!
- * \NOTE
- * cbdata->deleted must has to be checked before call the function and
- * return from the function call.
- */
- if (cbdata->deleted || cbdata->evt_cb(handle, cbdata->data) < 0 || cbdata->deleted) {
- s_info.disconn_cb_list = dlist_remove(s_info.disconn_cb_list, l);
- free(cbdata);
- }
- }
- s_info.processing_event_callback &= ~PROCESSING_DISCONNECTION;
-
- if (watch) {
- if (watch_item_destroy(handle, remove_id, remove_data) < 0) {
- ErrPrint("Failed to destroy watch item\n");
- }
- }
+ struct dlist *l;
+ struct dlist *n;
+ struct evtdata *cbdata;
+
+ s_info.processing_event_callback |= PROCESSING_DISCONNECTION;
+ dlist_foreach_safe(s_info.disconn_cb_list, l, n, cbdata) {
+ /*!
+ * \NOTE
+ * cbdata->deleted must has to be checked before call the function and
+ * return from the function call.
+ */
+ if (cbdata->deleted || cbdata->evt_cb(handle, cbdata->data) < 0 || cbdata->deleted) {
+ s_info.disconn_cb_list = dlist_remove(s_info.disconn_cb_list, l);
+ free(cbdata);
+ }
+ }
+ s_info.processing_event_callback &= ~PROCESSING_DISCONNECTION;
+
+ if (watch) {
+ if (watch_item_destroy(handle, remove_id, remove_data) < 0) {
+ ErrPrint("Failed to destroy watch item\n");
+ }
+ }
}
static int validate_handle(int fd)
{
- int error;
- socklen_t len;
+ int error;
+ socklen_t len;
- len = sizeof(error);
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
- ErrPrint("getsockopt: %s\n", strerror(errno));
- return 0;
- }
+ len = sizeof(error);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+ ErrPrint("getsockopt: %s\n", strerror(errno));
+ return 0;
+ }
- return !(error == EBADF);
+ return !(error == EBADF);
}
static gboolean client_cb(GIOChannel *src, GIOCondition cond, gpointer data)
{
- int client_fd;
- struct cbdata *cbdata = data;
- int ret;
-
- client_fd = g_io_channel_unix_get_fd(src);
-
- if (!(cond & G_IO_IN)) {
- DbgPrint("Client is disconencted\n");
- invoke_disconn_cb_list(client_fd, 0, 1, 1);
- secure_socket_destroy_handle(client_fd);
- return FALSE;
- }
-
- if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
- DbgPrint("Client connection is lost\n");
- invoke_disconn_cb_list(client_fd, 0, 1, 1);
- secure_socket_destroy_handle(client_fd);
- return FALSE;
- }
-
- ret = cbdata->service_cb(client_fd, cbdata->data);
- if (ret < 0) {
- DbgPrint("service callback returns %d < 0\n", ret);
- invoke_disconn_cb_list(client_fd, 0, 1, 1);
- secure_socket_destroy_handle(client_fd);
- return FALSE;
- }
-
- /* Check whether the socket FD is closed or not */
- if (!validate_handle(client_fd)) {
- invoke_disconn_cb_list(client_fd, 0, 1, 1);
- secure_socket_destroy_handle(client_fd);
- return FALSE;
- }
-
- return TRUE;
+ int client_fd;
+ struct cbdata *cbdata = data;
+ int ret;
+
+ client_fd = g_io_channel_unix_get_fd(src);
+
+ if (!(cond & G_IO_IN)) {
+ DbgPrint("Client is disconencted\n");
+ invoke_disconn_cb_list(client_fd, 0, 1, 1);
+ secure_socket_destroy_handle(client_fd);
+ return FALSE;
+ }
+
+ if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
+ DbgPrint("Client connection is lost\n");
+ invoke_disconn_cb_list(client_fd, 0, 1, 1);
+ secure_socket_destroy_handle(client_fd);
+ return FALSE;
+ }
+
+ ret = cbdata->service_cb(client_fd, cbdata->data);
+ if (ret < 0) {
+ DbgPrint("service callback returns %d < 0\n", ret);
+ invoke_disconn_cb_list(client_fd, 0, 1, 1);
+ secure_socket_destroy_handle(client_fd);
+ return FALSE;
+ }
+
+ /* Check whether the socket FD is closed or not */
+ if (!validate_handle(client_fd)) {
+ invoke_disconn_cb_list(client_fd, 0, 1, 1);
+ secure_socket_destroy_handle(client_fd);
+ return FALSE;
+ }
+
+ return TRUE;
}
static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer cbdata)
{
- int socket_fd;
- int client_fd;
- GIOChannel *gio;
- guint id;
-
- socket_fd = g_io_channel_unix_get_fd(src);
- if (!(cond & G_IO_IN)) {
- ErrPrint("Accept socket closed\n");
- watch_item_destroy_all(socket_fd);
- secure_socket_destroy_handle(socket_fd);
- free(cbdata);
- return FALSE;
- }
-
- if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
- ErrPrint("Client connection is lost\n");
- watch_item_destroy_all(socket_fd);
- secure_socket_destroy_handle(socket_fd);
- free(cbdata);
- return FALSE;
- }
-
- client_fd = secure_socket_get_connection_handle(socket_fd);
- if (client_fd < 0) {
- /* Keep server running */
- return TRUE;
- }
- DbgPrint("New connectino arrived: server(%d), client(%d)\n", socket_fd, client_fd);
+ int socket_fd;
+ int client_fd;
+ GIOChannel *gio;
+ guint id;
+
+ socket_fd = g_io_channel_unix_get_fd(src);
+ if (!(cond & G_IO_IN)) {
+ ErrPrint("Accept socket closed\n");
+ watch_item_destroy_all(socket_fd);
+ secure_socket_destroy_handle(socket_fd);
+ free(cbdata);
+ return FALSE;
+ }
- if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
+ if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
+ ErrPrint("Client connection is lost\n");
+ watch_item_destroy_all(socket_fd);
+ secure_socket_destroy_handle(socket_fd);
+ free(cbdata);
+ return FALSE;
+ }
- if (fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
+ client_fd = secure_socket_get_connection_handle(socket_fd);
+ if (client_fd < 0) {
+ /* Keep server running */
+ return TRUE;
+ }
+ DbgPrint("New connectino arrived: server(%d), client(%d)\n", socket_fd, client_fd);
- gio = g_io_channel_unix_new(client_fd);
- if (!gio) {
- ErrPrint("Failed to get gio\n");
- secure_socket_destroy_handle(client_fd);
- /* Keep server running */
- return TRUE;
- }
+ if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ if (fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ gio = g_io_channel_unix_new(client_fd);
+ if (!gio) {
+ ErrPrint("Failed to get gio\n");
+ secure_socket_destroy_handle(client_fd);
+ /* Keep server running */
+ return TRUE;
+ }
- g_io_channel_set_close_on_unref(gio, FALSE);
+ g_io_channel_set_close_on_unref(gio, FALSE);
- id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
- if (id == 0) {
- GError *err = NULL;
+ id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
+ if (id == 0) {
+ GError *err = NULL;
- ErrPrint("Failed to add IO watch\n");
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ ErrPrint("Failed to add IO watch\n");
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(client_fd);
+ /* Keep server running */
+ return TRUE;
}
+
g_io_channel_unref(gio);
- secure_socket_destroy_handle(client_fd);
+
+ invoke_con_cb_list(socket_fd, client_fd, id, NULL, 1);
+
+ if (!validate_handle(socket_fd)) {
+ watch_item_destroy_all(socket_fd);
+ return FALSE;
+ }
+
/* Keep server running */
return TRUE;
- }
+}
- g_io_channel_unref(gio);
+EAPI int com_core_server_create(const char *addr, int is_sync, const char *label, int (*service_cb)(int fd, void *data), void *data)
+{
+ GIOChannel *gio;
+ guint id;
+ int fd;
+ struct cbdata *cbdata;
+
+ cbdata = malloc(sizeof(*cbdata));
+ if (!cbdata) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
+ }
- invoke_con_cb_list(socket_fd, client_fd, id, NULL, 1);
+ cbdata->service_cb = service_cb;
+ cbdata->data = data;
- if (!validate_handle(socket_fd)) {
- watch_item_destroy_all(socket_fd);
- return FALSE;
- }
+ fd = secure_socket_create_server_with_permission(addr, label);
+ if (fd < 0) {
+ free(cbdata);
+ return fd;
+ }
- /* Keep server running */
- return TRUE;
-}
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
-EAPI int com_core_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
-{
- GIOChannel *gio;
- guint id;
- int fd;
- struct cbdata *cbdata;
-
- cbdata = malloc(sizeof(*cbdata));
- if (!cbdata) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return -ENOMEM;
- }
-
- cbdata->service_cb = service_cb;
- cbdata->data = data;
-
- fd = secure_socket_create_server(addr);
- if (fd < 0) {
- free(cbdata);
- return fd;
- }
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("fcntl: %s\n", strerror(errno));
- }
-
- if (!is_sync && fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("fcntl: %s\n", strerror(errno));
- }
-
- DbgPrint("Create new IO channel for server FD: %d\n", fd);
- gio = g_io_channel_unix_new(fd);
- if (!gio) {
- ErrPrint("Failed to create new io channel\n");
- free(cbdata);
- secure_socket_destroy_handle(fd);
- return -EIO;
- }
-
- g_io_channel_set_close_on_unref(gio, FALSE);
-
- id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc)accept_cb, cbdata);
- if (id == 0) {
- GError *err = NULL;
- ErrPrint("Failed to add IO watch\n");
- free(cbdata);
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ if (!is_sync && fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("fcntl: %s\n", strerror(errno));
}
- g_io_channel_unref(gio);
- secure_socket_destroy_handle(fd);
- return -EIO;
- }
- if (watch_item_create(fd, fd, id, cbdata) < 0) {
- GError *err = NULL;
+ DbgPrint("Create new IO channel for server FD: %d\n", fd);
+ gio = g_io_channel_unix_new(fd);
+ if (!gio) {
+ ErrPrint("Failed to create new io channel\n");
+ free(cbdata);
+ secure_socket_destroy_handle(fd);
+ return -EIO;
+ }
+
+ g_io_channel_set_close_on_unref(gio, FALSE);
+
+ id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc)accept_cb, cbdata);
+ if (id == 0) {
+ GError *err = NULL;
+ ErrPrint("Failed to add IO watch\n");
+ free(cbdata);
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(fd);
+ return -EIO;
+ }
- ErrPrint("Failed to create a watch item\n");
- g_source_remove(id);
+ if (watch_item_create(fd, fd, id, cbdata) < 0) {
+ GError *err = NULL;
- free(cbdata);
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ ErrPrint("Failed to create a watch item\n");
+ g_source_remove(id);
+
+ free(cbdata);
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(fd);
+ return -ENOMEM;
}
- g_io_channel_unref(gio);
- secure_socket_destroy_handle(fd);
- return -ENOMEM;
- }
- g_io_channel_unref(gio);
- return fd;
+ g_io_channel_unref(gio);
+ return fd;
}
EAPI int com_core_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
{
- GIOChannel *gio;
- guint id;
- int client_fd;
- struct cbdata *cbdata;
-
- cbdata = malloc(sizeof(*cbdata));
- if (!cbdata) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return -ENOMEM;
- }
-
- cbdata->service_cb = service_cb;
- cbdata->data = data;
-
- client_fd = secure_socket_create_client(addr);
- if (client_fd < 0) {
- free(cbdata);
- return client_fd;
- }
-
- if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
-
- if (!is_sync && fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
-
- gio = g_io_channel_unix_new(client_fd);
- if (!gio) {
- ErrPrint("Failed to create a new IO channel\n");
- free(cbdata);
- secure_socket_destroy_handle(client_fd);
- return -EIO;
- }
-
- g_io_channel_set_close_on_unref(gio, FALSE);
-
- id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
- if (id == 0) {
- GError *err = NULL;
- ErrPrint("Failed to add IO watch\n");
- free(cbdata);
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ GIOChannel *gio;
+ guint id;
+ int client_fd;
+ struct cbdata *cbdata;
+
+ cbdata = malloc(sizeof(*cbdata));
+ if (!cbdata) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
+ }
+
+ cbdata->service_cb = service_cb;
+ cbdata->data = data;
+
+ client_fd = secure_socket_create_client(addr);
+ if (client_fd < 0) {
+ free(cbdata);
+ return client_fd;
+ }
+
+ if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ if (!is_sync && fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ gio = g_io_channel_unix_new(client_fd);
+ if (!gio) {
+ ErrPrint("Failed to create a new IO channel\n");
+ free(cbdata);
+ secure_socket_destroy_handle(client_fd);
+ return -EIO;
}
- g_io_channel_unref(gio);
- secure_socket_destroy_handle(client_fd);
- return -EIO;
- }
- g_io_channel_unref(gio);
+ g_io_channel_set_close_on_unref(gio, FALSE);
+
+ id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
+ if (id == 0) {
+ GError *err = NULL;
+ ErrPrint("Failed to add IO watch\n");
+ free(cbdata);
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(client_fd);
+ return -EIO;
+ }
+
+ g_io_channel_unref(gio);
- invoke_con_cb_list(client_fd, client_fd, id, cbdata, 1);
- return client_fd;
+ invoke_con_cb_list(client_fd, client_fd, id, cbdata, 1);
+ return client_fd;
}
EAPI int com_core_add_event_callback(enum com_core_event_type type, int (*evt_cb)(int handle, void *data), void *data)
{
- struct evtdata *cbdata;
- cbdata = malloc(sizeof(*cbdata));
- if (!cbdata) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return -ENOMEM;
- }
-
- cbdata->evt_cb = evt_cb;
- cbdata->data = data;
- cbdata->deleted = 0;
-
- if (type == CONNECTOR_CONNECTED) {
- s_info.conn_cb_list = dlist_append(s_info.conn_cb_list, cbdata);
- } else {
- s_info.disconn_cb_list = dlist_append(s_info.disconn_cb_list, cbdata);
- }
- return 0;
+ struct evtdata *cbdata;
+ cbdata = malloc(sizeof(*cbdata));
+ if (!cbdata) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
+ }
+
+ cbdata->evt_cb = evt_cb;
+ cbdata->data = data;
+ cbdata->deleted = 0;
+
+ if (type == CONNECTOR_CONNECTED) {
+ s_info.conn_cb_list = dlist_append(s_info.conn_cb_list, cbdata);
+ } else {
+ s_info.disconn_cb_list = dlist_append(s_info.disconn_cb_list, cbdata);
+ }
+ return 0;
}
EAPI int com_core_recv_with_fd(int handle, char *buffer, int size, int *sender_pid, double timeout, int *fd)
{
- int readsize;
- int ret;
- int *recv_fd;
-
- fd_set set;
-
- recv_fd = fd;
- readsize = 0;
- while (size > 0) {
- FD_ZERO(&set);
- FD_SET(handle, &set);
-
- if (timeout > 0.0f) {
- struct timeval tv;
-
- tv.tv_sec = (unsigned long)timeout;
- tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
- ret = select(handle + 1, &set, NULL, NULL, &tv);
- } else if (timeout == 0.0f) {
- ret = select(handle + 1, &set, NULL, NULL, NULL);
- } else {
- ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
- return -EINVAL;
- }
+ int readsize;
+ int ret;
+ int *recv_fd;
+
+ fd_set set;
+
+ recv_fd = fd;
+ readsize = 0;
+ while (size > 0) {
+ FD_ZERO(&set);
+ FD_SET(handle, &set);
+
+ if (timeout > 0.0f) {
+ struct timeval tv;
+
+ tv.tv_sec = (unsigned long)timeout;
+ tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+ ret = select(handle + 1, &set, NULL, NULL, &tv);
+ } else if (timeout == 0.0f) {
+ ret = select(handle + 1, &set, NULL, NULL, NULL);
+ } else {
+ ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
+ return -EINVAL;
+ }
- if (ret < 0) {
- ret = -errno;
- if (errno == EINTR) {
- DbgPrint("Select receives INTR\n");
- continue;
- }
- ErrPrint("Error: %s\n", strerror(errno));
- return ret;
- } else if (ret == 0) {
- ErrPrint("Timeout expired\n");
- break;
- }
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EINTR) {
+ DbgPrint("Select receives INTR\n");
+ continue;
+ }
+ ErrPrint("Error: %s\n", strerror(errno));
+ return ret;
+ } else if (ret == 0) {
+ ErrPrint("Timeout expired\n");
+ break;
+ }
+
+ if (!FD_ISSET(handle, &set)) {
+ ErrPrint("Unexpected handle is toggled\n");
+ return -EINVAL;
+ }
- if (!FD_ISSET(handle, &set)) {
- ErrPrint("Unexpected handle is toggled\n");
- return -EINVAL;
+ ret = secure_socket_recv_with_fd(handle, buffer + readsize, size, sender_pid, recv_fd);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ DbgPrint("Retry to get data (%d:%d)\n", readsize, size);
+ continue;
+ }
+ DbgPrint("[%d] recv returns: %d\n", handle, ret);
+ return ret;
+ } else if (ret == 0) {
+ DbgPrint("Disconnected(req.size: %d)\n", size);
+ return 0;
+ }
+
+ recv_fd = NULL; /** Get it only for the first time */
+ size -= ret;
+ readsize += ret;
}
- ret = secure_socket_recv_with_fd(handle, buffer + readsize, size, sender_pid, recv_fd);
- if (ret < 0) {
- if (ret == -EAGAIN) {
- DbgPrint("Retry to get data (%d:%d)\n", readsize, size);
- continue;
- }
- DbgPrint("[%d] recv returns: %d\n", handle, ret);
- return ret;
- } else if (ret == 0) {
- DbgPrint("Disconnected(req.size: %d)\n", size);
- return 0;
- }
-
- recv_fd = NULL; /** Get it only for the first time */
- size -= ret;
- readsize += ret;
- }
-
- return readsize;
+ return readsize;
}
EAPI int com_core_recv(int handle, char *buffer, int size, int *sender_pid, double timeout)
{
- return com_core_recv_with_fd(handle, buffer, size, sender_pid, timeout, NULL);
+ return com_core_recv_with_fd(handle, buffer, size, sender_pid, timeout, NULL);
}
EAPI int com_core_send_with_fd(int handle, const char *buffer, int size, double timeout, int fd)
{
- int writesize;
- int ret;
+ int writesize;
+ int ret;
- fd_set set;
+ fd_set set;
- writesize = 0;
- while (size > 0) {
+ writesize = 0;
+ while (size > 0) {
- FD_ZERO(&set);
- FD_SET(handle, &set);
+ FD_ZERO(&set);
+ FD_SET(handle, &set);
- if (timeout > 0.0f) {
- struct timeval tv;
+ if (timeout > 0.0f) {
+ struct timeval tv;
- tv.tv_sec = (unsigned long)timeout;
- tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+ tv.tv_sec = (unsigned long)timeout;
+ tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
- ret = select(handle + 1, NULL, &set, NULL, &tv);
- } else if (timeout == 0.0f) {
- ret = select(handle + 1, NULL, &set, NULL, NULL);
- } else {
- ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
- return -EINVAL;
- }
+ ret = select(handle + 1, NULL, &set, NULL, &tv);
+ } else if (timeout == 0.0f) {
+ ret = select(handle + 1, NULL, &set, NULL, NULL);
+ } else {
+ ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
+ return -EINVAL;
+ }
- if (ret < 0) {
- ret = -errno;
- if (errno == EINTR) {
- DbgPrint("Select receives INTR\n");
- continue;
- }
- ErrPrint("Error: %s\n", strerror(errno));
- return ret;
- } else if (ret == 0) {
- ErrPrint("Timeout expired\n");
- break;
- }
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EINTR) {
+ DbgPrint("Select receives INTR\n");
+ continue;
+ }
+ ErrPrint("Error: %s\n", strerror(errno));
+ return ret;
+ } else if (ret == 0) {
+ ErrPrint("Timeout expired\n");
+ break;
+ }
+
+ if (!FD_ISSET(handle, &set)) {
+ ErrPrint("Unexpected handle is toggled\n");
+ return -EINVAL;
+ }
- if (!FD_ISSET(handle, &set)) {
- ErrPrint("Unexpected handle is toggled\n");
- return -EINVAL;
+ ret = secure_socket_send_with_fd(handle, buffer + writesize, size, fd);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ DbgPrint("Retry to send data (%d:%d)\n", writesize, size);
+ continue;
+ }
+ DbgPrint("Failed to send: %d\n", ret);
+ return ret;
+ } else if (ret == 0) {
+ DbgPrint("Disconnected? : Send bytes: 0\n");
+ return 0;
+ }
+
+ fd = -1; /** Send only once if it is fd */
+ size -= ret;
+ writesize += ret;
}
- ret = secure_socket_send_with_fd(handle, buffer + writesize, size, fd);
- if (ret < 0) {
- if (ret == -EAGAIN) {
- DbgPrint("Retry to send data (%d:%d)\n", writesize, size);
- continue;
- }
- DbgPrint("Failed to send: %d\n", ret);
- return ret;
- } else if (ret == 0) {
- DbgPrint("Disconnected? : Send bytes: 0\n");
- return 0;
- }
-
- fd = -1; /** Send only once if it is fd */
- size -= ret;
- writesize += ret;
- }
-
- return writesize;
+ return writesize;
}
EAPI int com_core_send(int handle, const char *buffer, int size, double timeout)
{
- return com_core_send_with_fd(handle, buffer, size, timeout, -1);
+ return com_core_send_with_fd(handle, buffer, size, timeout, -1);
}
EAPI void *com_core_del_event_callback(enum com_core_event_type type, int (*cb)(int handle, void *data), void *data)
{
- struct dlist *l;
- struct dlist *n;
- struct evtdata *cbdata;
-
- if (type == CONNECTOR_CONNECTED) {
- dlist_foreach_safe(s_info.conn_cb_list, l, n, cbdata) {
- if (cbdata->evt_cb == cb && cbdata->data == data) {
- void *data;
- data = cbdata->data;
-
- if ((s_info.processing_event_callback & PROCESSING_CONNECTION) == PROCESSING_CONNECTION) {
- cbdata->deleted = 1;
- } else {
- dlist_remove_data(s_info.conn_cb_list, cbdata);
- free(cbdata);
+ struct dlist *l;
+ struct dlist *n;
+ struct evtdata *cbdata;
+
+ if (type == CONNECTOR_CONNECTED) {
+ dlist_foreach_safe(s_info.conn_cb_list, l, n, cbdata) {
+ if (cbdata->evt_cb == cb && cbdata->data == data) {
+ void *data;
+ data = cbdata->data;
+
+ if ((s_info.processing_event_callback & PROCESSING_CONNECTION) == PROCESSING_CONNECTION) {
+ cbdata->deleted = 1;
+ } else {
+ dlist_remove_data(s_info.conn_cb_list, cbdata);
+ free(cbdata);
+ }
+
+ return data;
+ }
}
-
- return data;
- }
- }
- } else {
- dlist_foreach_safe(s_info.disconn_cb_list, l, n, cbdata) {
- if (cbdata->evt_cb == cb && cbdata->data == data) {
- void *data;
- data = cbdata->data;
-
- if ((s_info.processing_event_callback & PROCESSING_DISCONNECTION) == PROCESSING_DISCONNECTION) {
- cbdata->deleted = 1;
- } else {
- dlist_remove_data(s_info.disconn_cb_list, cbdata);
- free(cbdata);
+ } else {
+ dlist_foreach_safe(s_info.disconn_cb_list, l, n, cbdata) {
+ if (cbdata->evt_cb == cb && cbdata->data == data) {
+ void *data;
+ data = cbdata->data;
+
+ if ((s_info.processing_event_callback & PROCESSING_DISCONNECTION) == PROCESSING_DISCONNECTION) {
+ cbdata->deleted = 1;
+ } else {
+ dlist_remove_data(s_info.disconn_cb_list, cbdata);
+ free(cbdata);
+ }
+ return data;
+ }
}
- return data;
- }
}
- }
- return NULL;
+ return NULL;
}
EAPI int com_core_server_destroy(int handle)
{
- DbgPrint("Close server handle[%d]\n", handle);
- invoke_disconn_cb_list(handle, 1, 1, 1);
- secure_socket_destroy_handle(handle);
- return 0;
+ DbgPrint("Close server handle[%d]\n", handle);
+ invoke_disconn_cb_list(handle, 1, 1, 1);
+ secure_socket_destroy_handle(handle);
+ return 0;
}
EAPI int com_core_client_destroy(int handle)
{
- DbgPrint("Close client handle[%d]\n", handle);
- invoke_disconn_cb_list(handle, 1, 1, 1);
- secure_socket_destroy_handle(handle);
- return 0;
+ DbgPrint("Close client handle[%d]\n", handle);
+ invoke_disconn_cb_list(handle, 1, 1, 1);
+ secure_socket_destroy_handle(handle);
+ return 0;
}
/* End of a file */
diff --git a/src/com-core_packet-router.c b/src/com-core_packet-router.c
index ce582f7..55b57a7 100644
--- a/src/com-core_packet-router.c
+++ b/src/com-core_packet-router.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#define _GNU_SOURCE
#include <stdio.h>
@@ -459,13 +459,18 @@ static struct packet *service_handler(int handle, pid_t pid, const struct packet
}
result = NULL;
- for (i = 0; table[i].cmd; i++) {
- if (strcmp(table[i].cmd, packet_command(packet))) {
- continue;
- }
- result = table[i].handler(pid, handle, packet);
- break;
+ const char *cmd = packet_command(packet);
+ if (cmd) {
+ for (i = 0; table[i].cmd; i++) {
+
+ if (strcmp(table[i].cmd, cmd)) {
+ continue;
+ }
+
+ result = table[i].handler(pid, handle, packet);
+ break;
+ }
}
return result;
diff --git a/src/com-core_packet.c b/src/com-core_packet.c
index 41ace18..bf9814d 100644
--- a/src/com-core_packet.c
+++ b/src/com-core_packet.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#include <stdio.h>
#include <errno.h>
@@ -44,771 +44,792 @@
*/
static struct info {
- struct dlist *recv_list;
- struct dlist *request_list;
- char *addr;
+ struct dlist *recv_list;
+ struct dlist *request_list;
+ char *addr;
- struct {
- int (*server_create)(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
- int (*client_create)(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
- int (*server_destroy)(int handle);
- int (*client_destroy)(int handle);
+ struct {
+ int (*server_create)(const char *addr, int is_sync, const char *label, int (*service_cb)(int fd, void *data), void *data);
+ int (*client_create)(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data);
+ int (*server_destroy)(int handle);
+ int (*client_destroy)(int handle);
- int (*recv)(int handle, char *buffer, int size, int *sender_pid, double timeout);
- int (*send)(int handle, const char *buffer, int size, double timeout);
+ int (*recv)(int handle, char *buffer, int size, int *sender_pid, double timeout);
+ int (*send)(int handle, const char *buffer, int size, double timeout);
- int (*recv_with_fd)(int handle, char *buffer, int size, int *sender_pid, double timeout, int *fd);
- int (*send_with_fd)(int handle, const char *buffer, int size, double timeout, int fd);
- } vtable;
+ int (*recv_with_fd)(int handle, char *buffer, int size, int *sender_pid, double timeout, int *fd);
+ int (*send_with_fd)(int handle, const char *buffer, int size, double timeout, int fd);
+ } vtable;
- int initialized;
+ int initialized;
} s_info = {
- .recv_list = NULL,
- .request_list = NULL,
- .addr = NULL,
- .vtable = {
- .server_create = com_core_server_create,
- .client_create = com_core_client_create,
- .server_destroy = com_core_server_destroy,
- .client_destroy = com_core_client_destroy,
- .recv = com_core_recv,
- .send = com_core_send,
- .recv_with_fd = com_core_recv_with_fd,
- .send_with_fd = com_core_send_with_fd,
- },
- .initialized = 0,
+ .recv_list = NULL,
+ .request_list = NULL,
+ .addr = NULL,
+ .vtable = {
+ .server_create = com_core_server_create,
+ .client_create = com_core_client_create,
+ .server_destroy = com_core_server_destroy,
+ .client_destroy = com_core_client_destroy,
+ .recv = com_core_recv,
+ .send = com_core_send,
+ .recv_with_fd = com_core_recv_with_fd,
+ .send_with_fd = com_core_send_with_fd,
+ },
+ .initialized = 0,
};
struct request_ctx {
- pid_t pid;
- int handle;
+ pid_t pid;
+ int handle;
- struct packet *packet;
- int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data);
- void *data;
+ struct packet *packet;
+ int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data);
+ void *data;
- int inuse;
+ int inuse;
};
struct recv_ctx {
- enum {
- RECV_STATE_INIT,
- RECV_STATE_HEADER,
- RECV_STATE_BODY,
- RECV_STATE_READY
- } state;
- int handle;
- int offset;
- pid_t pid;
- struct packet *packet;
- double timeout;
-
- int inuse;
+ enum {
+ RECV_STATE_INIT,
+ RECV_STATE_HEADER,
+ RECV_STATE_BODY,
+ RECV_STATE_READY
+ } state;
+ int handle;
+ int offset;
+ pid_t pid;
+ struct packet *packet;
+ double timeout;
+
+ int inuse;
};
static inline struct request_ctx *find_request_ctx(int handle, double seq)
{
- struct request_ctx *ctx;
- struct dlist *l;
+ struct request_ctx *ctx;
+ struct dlist *l;
- dlist_foreach(s_info.request_list, l, ctx) {
- if (ctx->handle == handle && packet_seq(ctx->packet) == seq) {
- return ctx;
+ dlist_foreach(s_info.request_list, l, ctx) {
+ if (ctx->handle == handle && packet_seq(ctx->packet) == seq) {
+ return ctx;
+ }
}
- }
- return NULL;
+ return NULL;
}
static inline void destroy_request_ctx(struct request_ctx *ctx)
{
- struct dlist *l;
+ struct dlist *l;
- if (ctx->inuse) {
- return;
- }
+ if (ctx->inuse) {
+ return;
+ }
- l = dlist_find_data(s_info.request_list, ctx);
- if (!l) {
- return;
- }
+ l = dlist_find_data(s_info.request_list, ctx);
+ if (!l) {
+ return;
+ }
- s_info.request_list = dlist_remove(s_info.request_list, l);
+ s_info.request_list = dlist_remove(s_info.request_list, l);
- packet_unref(ctx->packet);
- free(ctx);
+ packet_unref(ctx->packet);
+ free(ctx);
}
static inline struct request_ctx *create_request_ctx(int handle)
{
- struct request_ctx *ctx;
+ struct request_ctx *ctx;
- ctx = malloc(sizeof(*ctx));
- if (!ctx) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
- ctx->handle = handle;
- ctx->pid = (pid_t)-1;
- ctx->packet = NULL;
- ctx->recv_cb = NULL;
- ctx->data = NULL;
- ctx->inuse = 0;
+ ctx->handle = handle;
+ ctx->pid = (pid_t)-1;
+ ctx->packet = NULL;
+ ctx->recv_cb = NULL;
+ ctx->data = NULL;
+ ctx->inuse = 0;
- s_info.request_list = dlist_append(s_info.request_list, ctx);
- return ctx;
+ s_info.request_list = dlist_append(s_info.request_list, ctx);
+ return ctx;
}
static inline struct recv_ctx *find_recv_ctx(int handle)
{
- struct recv_ctx *ctx;
- struct dlist *l;
+ struct recv_ctx *ctx;
+ struct dlist *l;
- dlist_foreach(s_info.recv_list, l, ctx) {
- if (ctx->handle == handle) {
- return ctx;
+ dlist_foreach(s_info.recv_list, l, ctx) {
+ if (ctx->handle == handle) {
+ return ctx;
+ }
}
- }
- return NULL;
+ return NULL;
}
static inline void recreate_recv_ctx(struct recv_ctx *ctx)
{
- if (ctx->packet) {
- packet_destroy(ctx->packet);
- ctx->packet = NULL;
- }
- ctx->state = RECV_STATE_INIT;
- ctx->offset = 0;
- ctx->pid = (pid_t)-1;
- // ctx->inuse
- // ctx->handle
- // ctx->timeout
+ if (ctx->packet) {
+ packet_destroy(ctx->packet);
+ ctx->packet = NULL;
+ }
+ ctx->state = RECV_STATE_INIT;
+ ctx->offset = 0;
+ ctx->pid = (pid_t)-1;
+ // ctx->inuse
+ // ctx->handle
+ // ctx->timeout
}
static inline void destroy_recv_ctx(struct recv_ctx *ctx)
{
- struct dlist *l;
+ struct dlist *l;
- if (ctx->inuse) {
- return;
- }
+ if (ctx->inuse) {
+ return;
+ }
- l = dlist_find_data(s_info.recv_list, ctx);
- if (!l) {
- return;
- }
+ l = dlist_find_data(s_info.recv_list, ctx);
+ if (!l) {
+ return;
+ }
- s_info.recv_list = dlist_remove(s_info.recv_list, l);
+ s_info.recv_list = dlist_remove(s_info.recv_list, l);
- packet_destroy(ctx->packet);
- free(ctx);
+ packet_destroy(ctx->packet);
+ free(ctx);
}
static inline struct recv_ctx *create_recv_ctx(int handle, double timeout)
{
- struct recv_ctx *ctx;
+ struct recv_ctx *ctx;
- ctx = malloc(sizeof(*ctx));
- if (!ctx) {
- ErrPrint("heap: %s\n", strerror(errno));
- return NULL;
- }
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx) {
+ ErrPrint("heap: %s\n", strerror(errno));
+ return NULL;
+ }
- ctx->state = RECV_STATE_INIT,
- ctx->offset = 0;
- ctx->packet = NULL;
- ctx->handle = handle;
- ctx->pid = (pid_t)-1;
- ctx->timeout = timeout;
- ctx->inuse = 0;
-
- s_info.recv_list = dlist_append(s_info.recv_list, ctx);
- return ctx;
+ ctx->state = RECV_STATE_INIT,
+ ctx->offset = 0;
+ ctx->packet = NULL;
+ ctx->handle = handle;
+ ctx->pid = (pid_t)-1;
+ ctx->timeout = timeout;
+ ctx->inuse = 0;
+
+ s_info.recv_list = dlist_append(s_info.recv_list, ctx);
+ return ctx;
}
static inline int packet_ready(int handle, struct recv_ctx *receive, struct method *table)
{
- struct request_ctx *request;
- double sequence;
- struct packet *result;
- register int i;
- int ret;
- const char *cmd;
- unsigned int cmd_idx;
+ struct request_ctx *request;
+ double sequence;
+ struct packet *result;
+ register int i;
+ int ret;
+ const char *cmd;
+ unsigned int cmd_idx;
- ret = 0;
+ ret = 0;
- switch (packet_type(receive->packet)) {
+ switch (packet_type(receive->packet)) {
case PACKET_ACK:
- sequence = packet_seq(receive->packet);
- request = find_request_ctx(handle, sequence);
- if (!request) {
- ErrPrint("This is not requested packet (%s)\n", packet_command(receive->packet));
+ sequence = packet_seq(receive->packet);
+ request = find_request_ctx(handle, sequence);
+ if (!request) {
+ ErrPrint("This is not requested packet (%s)\n", packet_command(receive->packet));
+ break;
+ }
+
+ if (request->recv_cb) {
+ request->inuse = 1;
+ receive->inuse = 1;
+ request->recv_cb(receive->pid, handle, receive->packet, request->data);
+ receive->inuse = 0;
+ request->inuse = 0;
+ }
+
+ destroy_request_ctx(request);
break;
- }
-
- if (request->recv_cb) {
- request->inuse = 1;
- receive->inuse = 1;
- request->recv_cb(receive->pid, handle, receive->packet, request->data);
- receive->inuse = 0;
- request->inuse = 0;
- }
-
- destroy_request_ctx(request);
- break;
case PACKET_REQ:
- cmd_idx = 0xFFFFFFFF;
- cmd = packet_command(receive->packet);
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *p_cmd_idx = (unsigned int *)cmd;
-
- /* Get rid of LSB 8 bits */
- cmd_idx = *p_cmd_idx >> 8;
- } else {
- for (i = 0; table[i].cmd; i++) {
- if (strcmp(table[i].cmd, packet_command(receive->packet))) {
- continue;
- }
-
- cmd_idx = (unsigned int)i;
- break;
+ cmd_idx = 0xFFFFFFFF;
+ cmd = packet_command(receive->packet);
+ if (cmd) {
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *p_cmd_idx = (unsigned int *)cmd;
+
+ /* Get rid of LSB 8 bits */
+ cmd_idx = *p_cmd_idx >> 8;
+ } else {
+ for (i = 0; table[i].cmd; i++) {
+ if (strcmp(table[i].cmd, cmd)) {
+ continue;
+ }
+
+ cmd_idx = (unsigned int)i;
+ break;
+ }
+ }
}
- }
-
- if (cmd_idx != 0xFFFFFFFF) {
- receive->inuse = 1;
- result = table[cmd_idx].handler(receive->pid, handle, receive->packet);
- receive->inuse = 0;
- if (result) {
- if (packet_fd(result) >= 0) {
- ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT, packet_fd(result));
- } else {
- ret = s_info.vtable.send(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT);
- }
-
- if (ret < 0) {
- ErrPrint("Failed to send an ack packet\n");
- } else {
- ret = 0;
- }
- packet_destroy(result);
+
+ if (cmd_idx != 0xFFFFFFFF) {
+ receive->inuse = 1;
+ result = table[cmd_idx].handler(receive->pid, handle, receive->packet);
+ receive->inuse = 0;
+ if (result) {
+ if (packet_fd(result) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT, packet_fd(result));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT);
+ }
+
+ if (ret < 0) {
+ ErrPrint("Failed to send an ack packet\n");
+ } else {
+ ret = 0;
+ }
+ packet_destroy(result);
+ }
}
- }
- break;
+ break;
case PACKET_REQ_NOACK:
- cmd_idx = 0xFFFFFFFF;
- cmd = packet_command(receive->packet);
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *p_cmd_idx = (unsigned int *)cmd;
-
- /* Get rid of LSB 8 bits */
- cmd_idx = *p_cmd_idx >> 8;
- } else {
- for (i = 0; table[i].cmd; i++) {
- if (strcmp(table[i].cmd, packet_command(receive->packet))) {
- continue;
- }
-
- cmd_idx = (unsigned int)i;
- break;
+ cmd_idx = 0xFFFFFFFF;
+ cmd = packet_command(receive->packet);
+ if (cmd) {
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *p_cmd_idx = (unsigned int *)cmd;
+
+ /* Get rid of LSB 8 bits */
+ cmd_idx = *p_cmd_idx >> 8;
+ } else {
+ for (i = 0; table[i].cmd; i++) {
+ if (strcmp(table[i].cmd, cmd)) {
+ continue;
+ }
+
+ cmd_idx = (unsigned int)i;
+ break;
+ }
+ }
}
- }
-
- if (cmd_idx != 0xFFFFFFFF) {
- receive->inuse = 1;
- result = table[cmd_idx].handler(receive->pid, handle, receive->packet);
- receive->inuse = 0;
- if (result) {
- packet_destroy(result);
+ if (cmd_idx != 0xFFFFFFFF) {
+ receive->inuse = 1;
+ result = table[cmd_idx].handler(receive->pid, handle, receive->packet);
+ receive->inuse = 0;
+ if (result) {
+ packet_destroy(result);
+ }
}
- }
- break;
+ break;
default:
- break;
- }
+ break;
+ }
- /*!
- * Return negative value will make call the disconnected_cb
- */
- return ret;
+ /*!
+ * Return negative value will make call the disconnected_cb
+ */
+ return ret;
}
static int client_disconnected_cb(int handle, void *data)
{
- struct recv_ctx *receive;
- struct request_ctx *request;
- struct dlist *l;
- struct dlist *n;
- int inuse_found = 0;
- pid_t pid = (pid_t)-1;
+ struct recv_ctx *receive;
+ struct request_ctx *request;
+ struct dlist *l;
+ struct dlist *n;
+ int inuse_found = 0;
+ pid_t pid = (pid_t)-1;
+
+ receive = find_recv_ctx(handle);
+ if (receive) {
+ pid = receive->pid;
+ }
- receive = find_recv_ctx(handle);
- if (receive) {
- pid = receive->pid;
- }
+ DbgPrint("Clean up all requests and a receive context for handle(%d) for pid(%d)\n", handle, pid);
- DbgPrint("Clean up all requests and a receive context for handle(%d) for pid(%d)\n", handle, pid);
+ dlist_foreach_safe(s_info.request_list, l, n, request) {
+ if (request->handle != handle) {
+ continue;
+ }
- dlist_foreach_safe(s_info.request_list, l, n, request) {
- if (request->handle != handle) {
- continue;
- }
+ if (request->inuse) {
+ inuse_found = 1;
+ continue;
+ }
- if (request->inuse) {
- inuse_found = 1;
- continue;
- }
+ if (request->recv_cb) {
+ request->recv_cb(pid, handle, NULL, request->data);
+ }
- if (request->recv_cb) {
- request->recv_cb(pid, handle, NULL, request->data);
+ destroy_request_ctx(request);
}
- destroy_request_ctx(request);
- }
-
- if (receive && !inuse_found) {
- destroy_recv_ctx(receive);
- }
+ if (receive && !inuse_found) {
+ destroy_recv_ctx(receive);
+ }
- return 0;
+ return 0;
}
static int service_cb(int handle, void *data)
{
- struct recv_ctx *receive;
- pid_t pid;
- int ret;
- int size;
- char *ptr;
- int fd = -1;
-
- receive = find_recv_ctx(handle);
- if (!receive) {
- receive = create_recv_ctx(handle, DEFAULT_TIMEOUT);
+ struct recv_ctx *receive;
+ pid_t pid;
+ int ret;
+ int size;
+ char *ptr;
+ int fd = -1;
+
+ receive = find_recv_ctx(handle);
if (!receive) {
- ErrPrint("Couldn't find or create a receive context\n");
- return -EIO;
+ receive = create_recv_ctx(handle, DEFAULT_TIMEOUT);
+ if (!receive) {
+ ErrPrint("Couldn't find or create a receive context\n");
+ return -EIO;
+ }
}
- }
- switch (receive->state) {
+ switch (receive->state) {
case RECV_STATE_INIT:
- receive->state = RECV_STATE_HEADER;
- receive->offset = 0;
+ receive->state = RECV_STATE_HEADER;
+ receive->offset = 0;
case RECV_STATE_HEADER:
- size = packet_header_size() - receive->offset;
- /*!
- * \note
- * Getting header
- */
- ptr = malloc(size);
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return -ENOMEM;
- }
-
- ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
- if (ret < 0) {
- ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
- free(ptr);
- return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
- } else if (ret > 0) {
- if (receive->pid != -1 && receive->pid != pid) {
- ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
- free(ptr);
- return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
+ size = packet_header_size() - receive->offset;
+ /*!
+ * \note
+ * Getting header
+ */
+ ptr = malloc(size);
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
}
- receive->pid = pid;
- receive->packet = packet_build(receive->packet, receive->offset, ptr, ret);
- free(ptr);
-
- if (!receive->packet) {
- ErrPrint("Built packet is not valid\n");
- return -EFAULT; /*!< Return negative value will invoke the client_disconnected_cb */
- }
-
- if (fd >= 0) {
- if (packet_fd(receive->packet) >= 0) {
- DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
- }
-
- packet_set_fd(receive->packet, fd);
+ ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
+ if (ret < 0) {
+ ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+ free(ptr);
+ return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
+ } else if (ret > 0) {
+ if (receive->pid != -1 && receive->pid != pid) {
+ ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+ free(ptr);
+ return -EIO; /*!< Return negative value will invoke the client_disconnected_cb */
+ }
+
+ receive->pid = pid;
+ receive->packet = packet_build(receive->packet, receive->offset, ptr, ret);
+ free(ptr);
+
+ if (!receive->packet) {
+ ErrPrint("Built packet is not valid\n");
+ return -EFAULT; /*!< Return negative value will invoke the client_disconnected_cb */
+ }
+
+ if (fd >= 0) {
+ if (packet_fd(receive->packet) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
+ }
+
+ packet_set_fd(receive->packet, fd);
+ }
+
+ receive->offset += ret;
+
+ if (receive->offset == packet_header_size()) {
+ if (packet_size(receive->packet) == receive->offset) {
+ receive->state = RECV_STATE_READY;
+ } else {
+ receive->state = RECV_STATE_BODY;
+ }
+ }
+ } else {
+ DbgPrint("ZERO bytes receives(%d)\n", pid);
+ free(ptr);
+ return -ECONNRESET;
}
-
- receive->offset += ret;
-
- if (receive->offset == packet_header_size()) {
- if (packet_size(receive->packet) == receive->offset) {
- receive->state = RECV_STATE_READY;
- } else {
- receive->state = RECV_STATE_BODY;
- }
- }
- } else {
- DbgPrint("ZERO bytes receives(%d)\n", pid);
- free(ptr);
- return -ECONNRESET;
- }
- break;
- case RECV_STATE_BODY:
- size = packet_size(receive->packet) - receive->offset;
- if (size == 0) {
- receive->state = RECV_STATE_READY;
break;
- }
- /*!
- * \note
- * Getting body
- */
- ptr = malloc(size);
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return -ENOMEM;
- }
-
- ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
- if (ret < 0) {
- ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
- free(ptr);
- return -EIO;
- } else if (ret > 0) {
- if (receive->pid != pid) {
- ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
- free(ptr);
- return -EIO;
- }
-
- receive->packet = packet_build(receive->packet, receive->offset, ptr, ret);
- free(ptr);
-
- if (!receive->packet) {
- ErrPrint("Built packet is not valid\n");
- return -EFAULT;
+ case RECV_STATE_BODY:
+ size = packet_size(receive->packet) - receive->offset;
+ if (size == 0) {
+ receive->state = RECV_STATE_READY;
+ break;
}
-
- if (fd >= 0) {
- if (packet_fd(receive->packet) >= 0) {
- DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
- }
-
- packet_set_fd(receive->packet, fd);
+ /*!
+ * \note
+ * Getting body
+ */
+ ptr = malloc(size);
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
}
- receive->offset += ret;
-
- if (receive->offset == packet_size(receive->packet)) {
- receive->state = RECV_STATE_READY;
+ ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
+ if (ret < 0) {
+ ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+ free(ptr);
+ return -EIO;
+ } else if (ret > 0) {
+ if (receive->pid != pid) {
+ ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
+ free(ptr);
+ return -EIO;
+ }
+
+ receive->packet = packet_build(receive->packet, receive->offset, ptr, ret);
+ free(ptr);
+
+ if (!receive->packet) {
+ ErrPrint("Built packet is not valid\n");
+ return -EFAULT;
+ }
+
+ if (fd >= 0) {
+ if (packet_fd(receive->packet) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
+ }
+
+ packet_set_fd(receive->packet, fd);
+ }
+
+ receive->offset += ret;
+
+ if (receive->offset == packet_size(receive->packet)) {
+ receive->state = RECV_STATE_READY;
+ }
+ } else {
+ DbgPrint("ZERO bytes receives(%d)\n", pid);
+ free(ptr);
+ return -ECONNRESET;
}
- } else {
- DbgPrint("ZERO bytes receives(%d)\n", pid);
- free(ptr);
- return -ECONNRESET;
- }
- break;
+ break;
case RECV_STATE_READY:
default:
- break;
- }
+ break;
+ }
- if (receive->state == RECV_STATE_READY) {
- ret = packet_ready(handle, receive, data);
- if (ret == 0) {
- /*!
- * If ret is negative value, the receive context will be destroyed from disconnected callback
- */
- recreate_recv_ctx(receive);
+ if (receive->state == RECV_STATE_READY) {
+ ret = packet_ready(handle, receive, data);
+ if (ret == 0) {
+ /*!
+ * If ret is negative value, the receive context will be destroyed from disconnected callback
+ */
+ recreate_recv_ctx(receive);
+ }
+ /*!
+ * if ret is negative value, disconnected_cb will be called after this function
+ */
+ } else {
+ ret = 0;
}
- /*!
- * if ret is negative value, disconnected_cb will be called after this function
- */
- } else {
- ret = 0;
- }
- return ret;
+ return ret;
}
EAPI int com_core_packet_async_send(int handle, struct packet *packet, double timeout, int (*recv_cb)(pid_t pid, int handle, const struct packet *packet, void *data), void *data)
{
- int ret;
- struct request_ctx *ctx;
-
- if (handle < 0 || !packet) {
- ErrPrint("Invalid argument\n");
- return -EINVAL;
- }
-
- if (packet_type(packet) != PACKET_REQ) {
- ErrPrint("Invalid packet - should be PACKET_REQ\n");
- return -EINVAL;
- }
-
- ctx = create_request_ctx(handle);
- if (!ctx) {
- return -ENOMEM;
- }
-
- ctx->recv_cb = recv_cb;
- ctx->data = data;
- ctx->packet = packet_ref(packet);
-
- if (packet_fd(packet) >= 0) {
- ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
- } else {
- ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
- }
- if (ret != packet_size(packet)) {
- ErrPrint("Send failed. %d <> %d (handle: %d)\n", ret, packet_size(packet), handle);
- destroy_request_ctx(ctx);
- return -EIO;
- }
-
- return 0;
+ int ret;
+ struct request_ctx *ctx;
+
+ if (handle < 0 || !packet) {
+ ErrPrint("Invalid argument\n");
+ return -EINVAL;
+ }
+
+ if (packet_type(packet) != PACKET_REQ) {
+ ErrPrint("Invalid packet - should be PACKET_REQ\n");
+ return -EINVAL;
+ }
+
+ ctx = create_request_ctx(handle);
+ if (!ctx) {
+ return -ENOMEM;
+ }
+
+ ctx->recv_cb = recv_cb;
+ ctx->data = data;
+ ctx->packet = packet_ref(packet);
+
+ if (packet_fd(packet) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
+ if (ret != packet_size(packet)) {
+ ErrPrint("Send failed. %d <> %d (handle: %d)\n", ret, packet_size(packet), handle);
+ destroy_request_ctx(ctx);
+ return -EIO;
+ }
+
+ return 0;
}
EAPI int com_core_packet_send_only(int handle, struct packet *packet)
{
- int ret;
-
- if (packet_type(packet) != PACKET_REQ_NOACK) {
- ErrPrint("Invalid type - should be PACKET_REQ_NOACK (%p)\n", packet);
- return -EINVAL;
- }
-
- if (packet_fd(packet) >= 0) {
- ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
- } else {
- ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
- }
- if (ret != packet_size(packet)) {
- ErrPrint("Failed to send whole packet\n");
- return -EIO;
- }
-
- return 0;
+ int ret;
+
+ if (packet_type(packet) != PACKET_REQ_NOACK) {
+ ErrPrint("Invalid type - should be PACKET_REQ_NOACK (%p)\n", packet);
+ return -EINVAL;
+ }
+
+ if (packet_fd(packet) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
+ if (ret != packet_size(packet)) {
+ ErrPrint("Failed to send whole packet\n");
+ return -EIO;
+ }
+
+ return 0;
}
EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet *packet, double timeout)
{
- int ret;
- int fd;
- pid_t pid;
- int offset;
- struct packet *result = NULL;
- void *ptr;
- int size;
- int recv_fd = -1;
-
- if (!addr || !packet) {
- ErrPrint("Invalid argument\n");
- return NULL;
- }
+ int ret;
+ int fd;
+ pid_t pid;
+ int offset;
+ struct packet *result = NULL;
+ void *ptr;
+ int size;
+ int recv_fd = -1;
+
+ if (!addr || !packet) {
+ ErrPrint("Invalid argument\n");
+ return NULL;
+ }
- fd = secure_socket_create_client(addr);
- if (fd < 0) {
- return NULL;
- }
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("fcntl: %s\n", strerror(errno));
- }
-
- if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
-
- if (packet_fd(packet) >= 0) {
- ret = com_core_send_with_fd(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
- } else {
- ret = com_core_send(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
- }
- if (ret < 0) {
- goto out;
- }
-
- ptr = malloc(packet_header_size());
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- goto out;
- }
-
- offset = 0;
- ret = com_core_recv_with_fd(fd, (char *)ptr, packet_header_size(), &pid, timeout, &recv_fd);
- if (ret <= 0) {
- DbgPrint("Recv returns %d\n", ret);
- free(ptr);
- goto out;
- } else {
- DbgPrint("Recv'd size: %d (header: %d) pid: %d\n", ret, packet_header_size(), pid);
- result = packet_build(result, offset, ptr, ret);
- offset += ret;
- free(ptr);
- if (!result) {
- ErrPrint("Failed to build a packet\n");
- goto out;
- }
-
- if (recv_fd >= 0) {
- if (packet_fd(result) >= 0) {
- DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
- }
-
- packet_set_fd(result, recv_fd);
- }
- }
-
- size = packet_payload_size(result);
- if (size < 0) {
- packet_destroy(result);
- result = NULL;
- goto out;
- }
-
- if (size == 0) {
- DbgPrint("Has no payload\n");
- goto out;
- }
-
- ptr = malloc(size);
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet_destroy(result);
- result = NULL;
- goto out;
- }
-
- ret = com_core_recv_with_fd(fd, (char *)ptr, size, &pid, timeout, &recv_fd);
- if (ret <= 0) {
- DbgPrint("Recv returns %d\n", ret);
- free(ptr);
- packet_destroy(result);
- result = NULL;
- } else {
- DbgPrint("Recv'd %d bytes (pid: %d)\n", ret, pid);
- result = packet_build(result, offset, ptr, ret);
- offset += ret;
- free(ptr);
-
- if (result && recv_fd >= 0) {
- if (packet_fd(result) >= 0) {
- DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
- }
-
- packet_set_fd(result, recv_fd);
- }
- }
+ fd = secure_socket_create_client(addr);
+ if (fd < 0) {
+ return NULL;
+ }
+
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
+
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ if (packet_fd(packet) >= 0) {
+ ret = com_core_send_with_fd(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = com_core_send(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
+ if (ret < 0) {
+ goto out;
+ }
+
+ ptr = malloc(packet_header_size());
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ goto out;
+ }
+
+ offset = 0;
+ ret = com_core_recv_with_fd(fd, (char *)ptr, packet_header_size(), &pid, timeout, &recv_fd);
+ if (ret <= 0) {
+ DbgPrint("Recv returns %d\n", ret);
+ free(ptr);
+ goto out;
+ } else {
+ DbgPrint("Recv'd size: %d (header: %d) pid: %d\n", ret, packet_header_size(), pid);
+ result = packet_build(result, offset, ptr, ret);
+ offset += ret;
+ free(ptr);
+ if (!result) {
+ ErrPrint("Failed to build a packet\n");
+ goto out;
+ }
+
+ if (recv_fd >= 0) {
+ if (packet_fd(result) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
+ }
+
+ packet_set_fd(result, recv_fd);
+ }
+ }
+
+ size = packet_payload_size(result);
+ if (size < 0) {
+ packet_destroy(result);
+ result = NULL;
+ goto out;
+ }
+
+ if (size == 0) {
+ DbgPrint("Has no payload\n");
+ goto out;
+ }
+
+ ptr = malloc(size);
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet_destroy(result);
+ result = NULL;
+ goto out;
+ }
+
+ ret = com_core_recv_with_fd(fd, (char *)ptr, size, &pid, timeout, &recv_fd);
+ if (ret <= 0) {
+ DbgPrint("Recv returns %d\n", ret);
+ free(ptr);
+ packet_destroy(result);
+ result = NULL;
+ } else {
+ DbgPrint("Recv'd %d bytes (pid: %d)\n", ret, pid);
+ result = packet_build(result, offset, ptr, ret);
+ offset += ret;
+ free(ptr);
+
+ if (result && recv_fd >= 0) {
+ if (packet_fd(result) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
+ }
+
+ packet_set_fd(result, recv_fd);
+ }
+ }
out:
- secure_socket_destroy_handle(fd);
- DbgPrint("Close connection: %d\n", fd);
- return result;
+ secure_socket_destroy_handle(fd);
+ DbgPrint("Close connection: %d\n", fd);
+ return result;
}
static inline int com_core_packet_init(void)
{
- int ret;
- if (s_info.initialized) {
- return 0;
- }
+ int ret;
+ if (s_info.initialized) {
+ return 0;
+ }
- ret = com_core_add_event_callback(CONNECTOR_DISCONNECTED, client_disconnected_cb, NULL);
- s_info.initialized = (ret == 0);
- return ret;
+ ret = com_core_add_event_callback(CONNECTOR_DISCONNECTED, client_disconnected_cb, NULL);
+ s_info.initialized = (ret == 0);
+ return ret;
}
static inline int com_core_packet_fini(void)
{
- if (!s_info.initialized) {
- return 0;
- }
+ if (!s_info.initialized) {
+ return 0;
+ }
- s_info.initialized = 0;
- com_core_del_event_callback(CONNECTOR_DISCONNECTED, client_disconnected_cb, NULL);
- return 0;
+ s_info.initialized = 0;
+ com_core_del_event_callback(CONNECTOR_DISCONNECTED, client_disconnected_cb, NULL);
+ return 0;
}
EAPI int com_core_packet_client_init(const char *addr, int is_sync, struct method *table)
{
- int ret;
+ int ret;
- ret = com_core_packet_init();
- if (ret < 0) {
- return ret;
- }
+ ret = com_core_packet_init();
+ if (ret < 0) {
+ return ret;
+ }
- ret = s_info.vtable.client_create(addr, is_sync, service_cb, table);
- if (ret < 0) {
- com_core_packet_fini();
- }
+ ret = s_info.vtable.client_create(addr, is_sync, service_cb, table);
+ if (ret < 0) {
+ com_core_packet_fini();
+ }
- return ret;
+ return ret;
}
EAPI int com_core_packet_client_fini(int handle)
{
- s_info.vtable.client_destroy(handle);
- com_core_packet_fini();
- return 0;
+ s_info.vtable.client_destroy(handle);
+ com_core_packet_fini();
+ return 0;
}
EAPI int com_core_packet_server_init(const char *addr, struct method *table)
{
- int ret;
+ int ret;
+
+ ret = com_core_packet_init();
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = s_info.vtable.server_create(addr, 0, NULL, service_cb, table);
+ if (ret < 0) {
+ com_core_packet_fini();
+ }
- ret = com_core_packet_init();
- if (ret < 0) {
return ret;
- }
+}
- ret = s_info.vtable.server_create(addr, 0, service_cb, table);
- if (ret < 0) {
- com_core_packet_fini();
- }
+EAPI int com_core_packet_server_init_with_permission(const char *addr, struct method *table, const char *label)
+{
+ int ret;
- return ret;
+ ret = com_core_packet_init();
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = s_info.vtable.server_create(addr, 0, label, service_cb, table);
+ if (ret < 0) {
+ com_core_packet_fini();
+ }
+
+ return ret;
}
+
EAPI int com_core_packet_server_fini(int handle)
{
- s_info.vtable.server_destroy(handle);
- com_core_packet_fini();
- return 0;
+ s_info.vtable.server_destroy(handle);
+ com_core_packet_fini();
+ return 0;
}
EAPI void com_core_packet_use_thread(int flag)
{
- if (s_info.initialized) {
- ErrPrint("com-core method is in use\n");
- return;
- }
-
- if (!!flag) {
- s_info.vtable.server_create = com_core_thread_server_create;
- s_info.vtable.client_create = com_core_thread_client_create;
- s_info.vtable.server_destroy = com_core_thread_server_destroy;
- s_info.vtable.client_destroy = com_core_thread_client_destroy;
- s_info.vtable.recv = com_core_thread_recv;
- s_info.vtable.send = com_core_thread_send;
- s_info.vtable.recv_with_fd = com_core_thread_recv_with_fd;
- s_info.vtable.send_with_fd = com_core_thread_send_with_fd;
- } else {
- s_info.vtable.server_create = com_core_server_create;
- s_info.vtable.client_create = com_core_client_create;
- s_info.vtable.server_destroy = com_core_server_destroy;
- s_info.vtable.client_destroy = com_core_client_destroy;
- s_info.vtable.recv = com_core_recv;
- s_info.vtable.send = com_core_send;
- s_info.vtable.recv_with_fd = com_core_recv_with_fd;
- s_info.vtable.send_with_fd = com_core_send_with_fd;
- }
+ if (s_info.initialized) {
+ ErrPrint("com-core method is in use\n");
+ return;
+ }
+
+ if (!!flag) {
+ s_info.vtable.server_create = com_core_thread_server_create;
+ s_info.vtable.client_create = com_core_thread_client_create;
+ s_info.vtable.server_destroy = com_core_thread_server_destroy;
+ s_info.vtable.client_destroy = com_core_thread_client_destroy;
+ s_info.vtable.recv = com_core_thread_recv;
+ s_info.vtable.send = com_core_thread_send;
+ s_info.vtable.recv_with_fd = com_core_thread_recv_with_fd;
+ s_info.vtable.send_with_fd = com_core_thread_send_with_fd;
+ } else {
+ s_info.vtable.server_create = com_core_server_create;
+ s_info.vtable.client_create = com_core_client_create;
+ s_info.vtable.server_destroy = com_core_server_destroy;
+ s_info.vtable.client_destroy = com_core_client_destroy;
+ s_info.vtable.recv = com_core_recv;
+ s_info.vtable.send = com_core_send;
+ s_info.vtable.recv_with_fd = com_core_recv_with_fd;
+ s_info.vtable.send_with_fd = com_core_send_with_fd;
+ }
}
/* End of a file */
diff --git a/src/com-core_thread.c b/src/com-core_thread.c
index 38c5a12..9995477 100644
--- a/src/com-core_thread.c
+++ b/src/com-core_thread.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#define _GNU_SOURCE
#include <stdio.h>
@@ -41,77 +41,77 @@ int errno;
#define EVENT_TERM 'e'
static struct {
- struct dlist *tcb_list;
- struct dlist *server_list;
+ struct dlist *tcb_list;
+ struct dlist *server_list;
} s_info = {
- .tcb_list = NULL,
- .server_list = NULL,
+ .tcb_list = NULL,
+ .server_list = NULL,
};
/*!
* \brief Representing the Server Object
*/
struct server {
- int (*service_cb)(int fd, void *data);
- void *data;
+ int (*service_cb)(int fd, void *data);
+ void *data;
- guint id;
- int handle;
+ guint id;
+ int handle;
};
/*!
* \brief This is used to holds a packet
*/
struct chunk {
- char *data;
- int offset;
- int size;
- pid_t pid;
- int fd;
+ char *data;
+ int offset;
+ int size;
+ pid_t pid;
+ int fd;
};
/*!
* \brief Thread Control Block
*/
struct tcb {
- pthread_t thid;
- int handle;
- struct dlist *chunk_list;
- int evt_pipe[PIPE_MAX];
- int ctrl_pipe[PIPE_MAX];
- pthread_mutex_t chunk_lock;
- guint id; /*!< g_io_watch */
-
- int server_handle;
-
- int (*service_cb)(int fd, void *data);
- void *data;
+ pthread_t thid;
+ int handle;
+ struct dlist *chunk_list;
+ int evt_pipe[PIPE_MAX];
+ int ctrl_pipe[PIPE_MAX];
+ pthread_mutex_t chunk_lock;
+ guint id; /*!< g_io_watch */
+
+ int server_handle;
+
+ int (*service_cb)(int fd, void *data);
+ void *data;
};
static ssize_t write_safe(int fd, const void *data, size_t bufsz)
{
- int ret;
- int again;
-
- do {
- again = 0;
- ret = write(fd, data, bufsz);
- if (ret < 0) {
- ret = -errno;
- switch (ret) {
- case -EAGAIN:
- case -EINTR:
- again = 1;
- ErrPrint("Interrupted[%d] Again[%d]\n", fd, -ret);
- break;
- default:
- ErrPrint("Failed to write: %s (%d)\n", strerror(-ret), -ret);
- return ret;
- }
- }
- } while (again);
+ int ret;
+ int again;
+
+ do {
+ again = 0;
+ ret = write(fd, data, bufsz);
+ if (ret < 0) {
+ ret = -errno;
+ switch (ret) {
+ case -EAGAIN:
+ case -EINTR:
+ again = 1;
+ ErrPrint("Interrupted[%d] Again[%d]\n", fd, -ret);
+ break;
+ default:
+ ErrPrint("Failed to write: %s (%d)\n", strerror(-ret), -ret);
+ return ret;
+ }
+ }
+ } while (again);
- return ret;
+ return ret;
}
/*!
@@ -120,17 +120,17 @@ static ssize_t write_safe(int fd, const void *data, size_t bufsz)
*/
static inline void server_destroy(struct server *server)
{
- dlist_remove_data(s_info.server_list, server);
+ dlist_remove_data(s_info.server_list, server);
- if (server->id > 0) {
- g_source_remove(server->id);
- }
+ if (server->id > 0) {
+ g_source_remove(server->id);
+ }
- if (server->handle > 0) {
- secure_socket_destroy_handle(server->handle);
- }
+ if (server->handle > 0) {
+ secure_socket_destroy_handle(server->handle);
+ }
- free(server);
+ free(server);
}
/*!
@@ -139,20 +139,20 @@ static inline void server_destroy(struct server *server)
*/
static inline struct server *server_create(int handle, int (*service_cb)(int fd, void *data), void *data)
{
- struct server *server;
+ struct server *server;
- server = malloc(sizeof(*server));
- if (!server) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
+ server = malloc(sizeof(*server));
+ if (!server) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
- server->handle = handle;
- server->service_cb = service_cb;
- server->data = data;
+ server->handle = handle;
+ server->service_cb = service_cb;
+ server->data = data;
- s_info.server_list = dlist_append(s_info.server_list, server);
- return server;
+ s_info.server_list = dlist_append(s_info.server_list, server);
+ return server;
}
/*!
@@ -161,8 +161,8 @@ static inline struct server *server_create(int handle, int (*service_cb)(int fd,
*/
static inline void destroy_chunk(struct chunk *chunk)
{
- free(chunk->data);
- free(chunk);
+ free(chunk->data);
+ free(chunk);
}
/*!
@@ -171,33 +171,33 @@ static inline void destroy_chunk(struct chunk *chunk)
*/
static inline void terminate_thread(struct tcb *tcb)
{
- int status;
- struct dlist *l;
- struct dlist *n;
- void *res = NULL;
- struct chunk *chunk;
-
- if (write_safe(tcb->ctrl_pipe[PIPE_WRITE], &tcb, sizeof(tcb)) != sizeof(tcb)) {
- ErrPrint("Unable to write CTRL pipe (%d)\n", sizeof(tcb));
- }
-
- secure_socket_destroy_handle(tcb->handle);
-
- status = pthread_join(tcb->thid, &res);
- if (status != 0) {
- ErrPrint("Join: %s\n", strerror(status));
- } else {
- ErrPrint("Thread returns: %d\n", (int)res);
- }
-
- dlist_foreach_safe(tcb->chunk_list, l, n, chunk) {
- /*!
- * Discarding all packets
- */
- DbgPrint("Discarding chunks\n");
- tcb->chunk_list = dlist_remove(tcb->chunk_list, l);
- destroy_chunk(chunk);
- }
+ int status;
+ struct dlist *l;
+ struct dlist *n;
+ void *res = NULL;
+ struct chunk *chunk;
+
+ if (write_safe(tcb->ctrl_pipe[PIPE_WRITE], &tcb, sizeof(tcb)) != sizeof(tcb)) {
+ ErrPrint("Unable to write CTRL pipe (%d)\n", sizeof(tcb));
+ }
+
+ secure_socket_destroy_handle(tcb->handle);
+
+ status = pthread_join(tcb->thid, &res);
+ if (status != 0) {
+ ErrPrint("Join: %s\n", strerror(status));
+ } else {
+ ErrPrint("Thread returns: %d\n", (int)res);
+ }
+
+ dlist_foreach_safe(tcb->chunk_list, l, n, chunk) {
+ /*!
+ * Discarding all packets
+ */
+ DbgPrint("Discarding chunks\n");
+ tcb->chunk_list = dlist_remove(tcb->chunk_list, l);
+ destroy_chunk(chunk);
+ }
}
/*!
@@ -206,21 +206,21 @@ static inline void terminate_thread(struct tcb *tcb)
*/
static inline void chunk_remove(struct tcb *tcb, struct chunk *chunk)
{
- char event_ch;
+ char event_ch;
- /* Consuming the event */
- if (read(tcb->evt_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
- ErrPrint("Failed to get readsize\n");
- return;
- }
+ /* Consuming the event */
+ if (read(tcb->evt_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
+ ErrPrint("Failed to get readsize\n");
+ return;
+ }
- CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
+ CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
- dlist_remove_data(tcb->chunk_list, chunk);
+ dlist_remove_data(tcb->chunk_list, chunk);
- CRITICAL_SECTION_END(&tcb->chunk_lock);
+ CRITICAL_SECTION_END(&tcb->chunk_lock);
- destroy_chunk(chunk);
+ destroy_chunk(chunk);
}
/*!
@@ -229,32 +229,32 @@ static inline void chunk_remove(struct tcb *tcb, struct chunk *chunk)
*/
static inline int chunk_append(struct tcb *tcb, struct chunk *chunk)
{
- char event_ch = EVENT_READY;
- int ret;
+ char event_ch = EVENT_READY;
+ int ret;
- CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
+ CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
- tcb->chunk_list = dlist_append(tcb->chunk_list, chunk);
+ tcb->chunk_list = dlist_append(tcb->chunk_list, chunk);
- CRITICAL_SECTION_END(&tcb->chunk_lock);
+ CRITICAL_SECTION_END(&tcb->chunk_lock);
- ret = write_safe(tcb->evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch));
- if (ret < 0) {
- CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
+ ret = write_safe(tcb->evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch));
+ if (ret < 0) {
+ CRITICAL_SECTION_BEGIN(&tcb->chunk_lock);
- dlist_remove_data(tcb->chunk_list, chunk);
+ dlist_remove_data(tcb->chunk_list, chunk);
- CRITICAL_SECTION_END(&tcb->chunk_lock);
- return ret;
- }
+ CRITICAL_SECTION_END(&tcb->chunk_lock);
+ return ret;
+ }
- if (ret != sizeof(event_ch)) {
- ErrPrint("Failed to trigger reader\n");
- }
+ if (ret != sizeof(event_ch)) {
+ ErrPrint("Failed to trigger reader\n");
+ }
- /* Take a breathe */
- pthread_yield();
- return 0;
+ /* Take a breathe */
+ pthread_yield();
+ return 0;
}
/*!
@@ -263,44 +263,44 @@ static inline int chunk_append(struct tcb *tcb, struct chunk *chunk)
*/
static inline int wait_event(struct tcb *tcb, double timeout)
{
- fd_set set;
- int ret;
-
- FD_ZERO(&set);
- FD_SET(tcb->evt_pipe[PIPE_READ], &set);
-
- if (timeout > 0.0f) {
- struct timeval tv;
- tv.tv_sec = (unsigned long)timeout;
- tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
- ret = select(tcb->evt_pipe[PIPE_READ] + 1, &set, NULL, NULL, &tv);
- } else if (timeout == 0.0f) {
- ret = select(tcb->evt_pipe[PIPE_READ] + 1, &set, NULL, NULL, NULL);
- } else {
- ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
- return -EINVAL;
- }
-
- if (ret < 0) {
- ret = -errno;
- if (errno == EINTR) {
- DbgPrint("Select receives INTR\n");
- return -EAGAIN;
+ fd_set set;
+ int ret;
+
+ FD_ZERO(&set);
+ FD_SET(tcb->evt_pipe[PIPE_READ], &set);
+
+ if (timeout > 0.0f) {
+ struct timeval tv;
+ tv.tv_sec = (unsigned long)timeout;
+ tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+ ret = select(tcb->evt_pipe[PIPE_READ] + 1, &set, NULL, NULL, &tv);
+ } else if (timeout == 0.0f) {
+ ret = select(tcb->evt_pipe[PIPE_READ] + 1, &set, NULL, NULL, NULL);
+ } else {
+ ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
+ return -EINVAL;
}
- ErrPrint("Error: %s\n", strerror(errno));
- return ret;
- } else if (ret == 0) {
- ErrPrint("Timeout expired\n");
- return -ETIMEDOUT;
- }
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EINTR) {
+ DbgPrint("Select receives INTR\n");
+ return -EAGAIN;
+ }
+
+ ErrPrint("Error: %s\n", strerror(errno));
+ return ret;
+ } else if (ret == 0) {
+ ErrPrint("Timeout expired\n");
+ return -ETIMEDOUT;
+ }
- if (!FD_ISSET(tcb->evt_pipe[PIPE_READ], &set)) {
- ErrPrint("Unexpected handle is toggled\n");
- return -EINVAL;
- }
+ if (!FD_ISSET(tcb->evt_pipe[PIPE_READ], &set)) {
+ ErrPrint("Unexpected handle is toggled\n");
+ return -EINVAL;
+ }
- return 0;
+ return 0;
}
/*!
@@ -309,26 +309,26 @@ static inline int wait_event(struct tcb *tcb, double timeout)
*/
static inline struct chunk *create_chunk(int size)
{
- struct chunk *chunk;
+ struct chunk *chunk;
- chunk = malloc(sizeof(*chunk));
- if (!chunk) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
+ chunk = malloc(sizeof(*chunk));
+ if (!chunk) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
- chunk->data = malloc(size);
- if (!chunk->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- free(chunk);
- return NULL;
- }
+ chunk->data = malloc(size);
+ if (!chunk->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(chunk);
+ return NULL;
+ }
- chunk->pid = (pid_t)-1;
- chunk->size = size;
- chunk->offset = 0;
- chunk->fd = -1;
- return chunk;
+ chunk->pid = (pid_t)-1;
+ chunk->size = size;
+ chunk->offset = 0;
+ chunk->fd = -1;
+ return chunk;
}
/*!
@@ -337,106 +337,106 @@ static inline struct chunk *create_chunk(int size)
*/
static void *client_cb(void *data)
{
- struct tcb *tcb = data;
- struct chunk *chunk;
- int ret = 0;
- fd_set set;
- int readsize;
- char event_ch;
- int fd;
-
- DbgPrint("Thread is created for %d (server: %d)\n", tcb->handle, tcb->server_handle);
- /*!
- * \NOTE
- * Read all data from the socket as possible as it can do
- */
- while (1) {
- FD_ZERO(&set);
- FD_SET(tcb->handle, &set);
- FD_SET(tcb->ctrl_pipe[PIPE_READ], &set);
+ struct tcb *tcb = data;
+ struct chunk *chunk;
+ int ret = 0;
+ fd_set set;
+ int readsize;
+ char event_ch;
+ int fd;
+
+ DbgPrint("Thread is created for %d (server: %d)\n", tcb->handle, tcb->server_handle);
+ /*!
+ * \NOTE
+ * Read all data from the socket as possible as it can do
+ */
+ while (1) {
+ FD_ZERO(&set);
+ FD_SET(tcb->handle, &set);
+ FD_SET(tcb->ctrl_pipe[PIPE_READ], &set);
+
+ fd = tcb->handle > tcb->ctrl_pipe[PIPE_READ] ? tcb->handle : tcb->ctrl_pipe[PIPE_READ];
+
+ ret = select(fd + 1, &set, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ DbgPrint("Select receives INTR\n");
+ continue;
+ }
+ ret = -errno;
+ /*!< Error */
+ ErrPrint("Error: %s\n", strerror(errno));
+ break;
+ } else if (ret == 0) {
+ ErrPrint("What happens? [%d]\n", tcb->handle);
+ continue;
+ }
- fd = tcb->handle > tcb->ctrl_pipe[PIPE_READ] ? tcb->handle : tcb->ctrl_pipe[PIPE_READ];
+ if (FD_ISSET(tcb->ctrl_pipe[PIPE_READ], &set)) {
+ DbgPrint("Thread is canceled\n");
+ ret = -ECANCELED;
+ break;
+ }
- ret = select(fd + 1, &set, NULL, NULL, NULL);
- if (ret < 0) {
- if (errno == EINTR) {
- DbgPrint("Select receives INTR\n");
- continue;
- }
- ret = -errno;
- /*!< Error */
- ErrPrint("Error: %s\n", strerror(errno));
- break;
- } else if (ret == 0) {
- ErrPrint("What happens? [%d]\n", tcb->handle);
- continue;
- }
+ if (!FD_ISSET(tcb->handle, &set)) {
+ ErrPrint("Unexpected handle is toggled\n");
+ ret = -EINVAL;
+ break;
+ }
- if (FD_ISSET(tcb->ctrl_pipe[PIPE_READ], &set)) {
- DbgPrint("Thread is canceled\n");
- ret = -ECANCELED;
- break;
- }
+ readsize = 0;
+ ret = ioctl(tcb->handle, FIONREAD, &readsize);
+ if (ret < 0) {
+ ErrPrint("ioctl: %s\n", strerror(errno));
+ break;
+ }
- if (!FD_ISSET(tcb->handle, &set)) {
- ErrPrint("Unexpected handle is toggled\n");
- ret = -EINVAL;
- break;
- }
+ if (readsize <= 0) {
+ ErrPrint("Available data: %d\n", readsize);
+ ret = -ECONNRESET;
+ break;
+ }
- readsize = 0;
- ret = ioctl(tcb->handle, FIONREAD, &readsize);
- if (ret < 0) {
- ErrPrint("ioctl: %s\n", strerror(errno));
- break;
- }
+ chunk = create_chunk(readsize);
+ if (!chunk) {
+ ErrPrint("Failed to create a new chunk: %d\n", readsize);
+ ret = -ENOMEM;
+ break;
+ }
- if (readsize <= 0) {
- ErrPrint("Available data: %d\n", readsize);
- ret = -ECONNRESET;
- break;
- }
+ ret = secure_socket_recv_with_fd(tcb->handle, chunk->data, chunk->size, &chunk->pid, &chunk->fd);
+ if (ret <= 0) {
+ destroy_chunk(chunk);
+ if (ret == -EAGAIN) {
+ DbgPrint("Retry to get data\n");
+ continue;
+ }
- chunk = create_chunk(readsize);
- if (!chunk) {
- ErrPrint("Failed to create a new chunk: %d\n", readsize);
- ret = -ENOMEM;
- break;
- }
+ DbgPrint("Recv returns: %d\n", ret);
+ break;
+ }
- ret = secure_socket_recv_with_fd(tcb->handle, chunk->data, chunk->size, &chunk->pid, &chunk->fd);
- if (ret <= 0) {
- destroy_chunk(chunk);
- if (ret == -EAGAIN) {
- DbgPrint("Retry to get data\n");
- continue;
- }
+ /* Update chunk size */
+ chunk->size = ret;
- DbgPrint("Recv returns: %d\n", ret);
- break;
+ /*!
+ * Count of chunk elements are same with PIPE'd data
+ */
+ if (chunk_append(tcb, chunk) < 0) {
+ destroy_chunk(chunk);
+ break;
+ }
}
- /* Update chunk size */
- chunk->size = ret;
+ DbgPrint("Client CB is terminated (%d)\n", tcb->handle);
+ /* Wake up main thread to get disconnected event */
+ event_ch = EVENT_TERM;
- /*!
- * Count of chunk elements are same with PIPE'd data
- */
- if (chunk_append(tcb, chunk) < 0) {
- destroy_chunk(chunk);
- break;
+ if (write_safe(tcb->evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
+ ErrPrint("%d byte is not written\n", sizeof(event_ch));
}
- }
-
- DbgPrint("Client CB is terminated (%d)\n", tcb->handle);
- /* Wake up main thread to get disconnected event */
- event_ch = EVENT_TERM;
-
- if (write_safe(tcb->evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
- ErrPrint("%d byte is not written\n", sizeof(event_ch));
- }
- return (void *)(unsigned long)ret;
+ return (void *)(unsigned long)ret;
}
/*!
@@ -445,23 +445,23 @@ static void *client_cb(void *data)
*/
static inline void tcb_destroy(struct tcb *tcb)
{
- int status;
+ int status;
- dlist_remove_data(s_info.tcb_list, tcb);
+ dlist_remove_data(s_info.tcb_list, tcb);
- if (tcb->id > 0) {
- g_source_remove(tcb->id);
- }
+ if (tcb->id > 0) {
+ g_source_remove(tcb->id);
+ }
- CLOSE_PIPE(tcb->evt_pipe);
- CLOSE_PIPE(tcb->ctrl_pipe);
+ CLOSE_PIPE(tcb->evt_pipe);
+ CLOSE_PIPE(tcb->ctrl_pipe);
- status = pthread_mutex_destroy(&tcb->chunk_lock);
- if (status != 0) {
- ErrPrint("Failed to destroy mutex: %s\n", strerror(status));
- }
+ status = pthread_mutex_destroy(&tcb->chunk_lock);
+ if (status != 0) {
+ ErrPrint("Failed to destroy mutex: %s\n", strerror(status));
+ }
- free(tcb);
+ free(tcb);
}
/*!
@@ -470,41 +470,41 @@ static inline void tcb_destroy(struct tcb *tcb)
*/
static gboolean evt_pipe_cb(GIOChannel *src, GIOCondition cond, gpointer data)
{
- int pipe_read;
- struct tcb *tcb = data;
- int ret;
+ int pipe_read;
+ struct tcb *tcb = data;
+ int ret;
- pipe_read = g_io_channel_unix_get_fd(src);
+ pipe_read = g_io_channel_unix_get_fd(src);
- if (tcb->evt_pipe[PIPE_READ] != pipe_read) {
- ErrPrint("Closed handle (%d <> %d)\n", tcb->evt_pipe[PIPE_READ], pipe_read);
- goto errout;
- }
+ if (tcb->evt_pipe[PIPE_READ] != pipe_read) {
+ ErrPrint("Closed handle (%d <> %d)\n", tcb->evt_pipe[PIPE_READ], pipe_read);
+ goto errout;
+ }
- if (!(cond & G_IO_IN)) {
- ErrPrint("PIPE is not valid\n");
- goto errout;
- }
+ if (!(cond & G_IO_IN)) {
+ ErrPrint("PIPE is not valid\n");
+ goto errout;
+ }
- if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
- ErrPrint("PIPE is not valid\n");
- goto errout;
- }
+ if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
+ ErrPrint("PIPE is not valid\n");
+ goto errout;
+ }
- ret = tcb->service_cb(tcb->handle, tcb->data);
- if (ret < 0) {
- DbgPrint("Service callback returns %d < 0\n", ret);
- goto errout;
- }
+ ret = tcb->service_cb(tcb->handle, tcb->data);
+ if (ret < 0) {
+ DbgPrint("Service callback returns %d < 0\n", ret);
+ goto errout;
+ }
- return TRUE;
+ return TRUE;
errout:
- DbgPrint("Disconnecting\n");
- invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
- terminate_thread(tcb);
- tcb_destroy(tcb);
- return FALSE;
+ DbgPrint("Disconnecting\n");
+ invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
+ terminate_thread(tcb);
+ tcb_destroy(tcb);
+ return FALSE;
}
/*!
@@ -513,54 +513,54 @@ errout:
*/
static inline struct tcb *tcb_create(int client_fd, int is_sync, int (*service_cb)(int fd, void *data), void *data)
{
- struct tcb *tcb;
- int status;
+ struct tcb *tcb;
+ int status;
- tcb = malloc(sizeof(*tcb));
- if (!tcb) {
- ErrPrint("Error: %s\n", strerror(errno));
- return NULL;
- }
+ tcb = malloc(sizeof(*tcb));
+ if (!tcb) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return NULL;
+ }
- tcb->handle = client_fd;
- tcb->chunk_list = NULL;
- tcb->service_cb = service_cb;
- tcb->data = data;
- tcb->id = 0;
+ tcb->handle = client_fd;
+ tcb->chunk_list = NULL;
+ tcb->service_cb = service_cb;
+ tcb->data = data;
+ tcb->id = 0;
- status = pthread_mutex_init(&tcb->chunk_lock, NULL);
- if (status != 0) {
- ErrPrint("Error: %s\n", strerror(status));
- free(tcb);
- return NULL;
- }
-
- if (pipe2(tcb->evt_pipe, O_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- status = pthread_mutex_destroy(&tcb->chunk_lock);
+ status = pthread_mutex_init(&tcb->chunk_lock, NULL);
if (status != 0) {
- ErrPrint("Error: %s\n", strerror(status));
+ ErrPrint("Error: %s\n", strerror(status));
+ free(tcb);
+ return NULL;
}
- free(tcb);
- return NULL;
- }
- if (pipe2(tcb->ctrl_pipe, O_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
+ if (pipe2(tcb->evt_pipe, O_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ status = pthread_mutex_destroy(&tcb->chunk_lock);
+ if (status != 0) {
+ ErrPrint("Error: %s\n", strerror(status));
+ }
+ free(tcb);
+ return NULL;
+ }
- CLOSE_PIPE(tcb->evt_pipe);
+ if (pipe2(tcb->ctrl_pipe, O_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
- status = pthread_mutex_destroy(&tcb->chunk_lock);
- if (status != 0) {
- ErrPrint("Error: %s\n", strerror(status));
- }
+ CLOSE_PIPE(tcb->evt_pipe);
- free(tcb);
- return NULL;
- }
+ status = pthread_mutex_destroy(&tcb->chunk_lock);
+ if (status != 0) {
+ ErrPrint("Error: %s\n", strerror(status));
+ }
+
+ free(tcb);
+ return NULL;
+ }
- DbgPrint("[%d] New TCB created: R(%d), W(%d)\n", client_fd, tcb->evt_pipe[PIPE_READ], tcb->evt_pipe[PIPE_WRITE]);
- return tcb;
+ DbgPrint("[%d] New TCB created: R(%d), W(%d)\n", client_fd, tcb->evt_pipe[PIPE_READ], tcb->evt_pipe[PIPE_WRITE]);
+ return tcb;
}
/*!
@@ -569,115 +569,115 @@ static inline struct tcb *tcb_create(int client_fd, int is_sync, int (*service_c
*/
static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer data)
{
- int socket_fd;
- int fd;
- int ret;
- struct tcb *tcb;
- GIOChannel *gio;
- struct server *server = data;
- pthread_attr_t attr;
- pthread_attr_t *pattr = NULL;
-
- socket_fd = g_io_channel_unix_get_fd(src);
- if (!(cond & G_IO_IN)) {
- ErrPrint("Accept socket closed\n");
- server_destroy(server);
- return FALSE;
- }
+ int socket_fd;
+ int fd;
+ int ret;
+ struct tcb *tcb;
+ GIOChannel *gio;
+ struct server *server = data;
+ pthread_attr_t attr;
+ pthread_attr_t *pattr = NULL;
+
+ socket_fd = g_io_channel_unix_get_fd(src);
+ if (!(cond & G_IO_IN)) {
+ ErrPrint("Accept socket closed\n");
+ server_destroy(server);
+ return FALSE;
+ }
- if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
- DbgPrint("Socket connection is lost\n");
- server_destroy(server);
- return FALSE;
- }
+ if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) {
+ DbgPrint("Socket connection is lost\n");
+ server_destroy(server);
+ return FALSE;
+ }
- fd = secure_socket_get_connection_handle(socket_fd);
- if (fd < 0) {
- ErrPrint("Failed to get client fd from socket\n");
- server_destroy(server);
- return FALSE;
- }
+ fd = secure_socket_get_connection_handle(socket_fd);
+ if (fd < 0) {
+ ErrPrint("Failed to get client fd from socket\n");
+ server_destroy(server);
+ return FALSE;
+ }
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
- if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
- tcb = tcb_create(fd, 0, server->service_cb, server->data);
- if (!tcb) {
- ErrPrint("Failed to create a TCB\n");
- secure_socket_destroy_handle(fd);
- server_destroy(server);
- return FALSE;
- }
+ tcb = tcb_create(fd, 0, server->service_cb, server->data);
+ if (!tcb) {
+ ErrPrint("Failed to create a TCB\n");
+ secure_socket_destroy_handle(fd);
+ server_destroy(server);
+ return FALSE;
+ }
- tcb->server_handle = socket_fd;
+ tcb->server_handle = socket_fd;
- s_info.tcb_list = dlist_append(s_info.tcb_list, tcb);
+ s_info.tcb_list = dlist_append(s_info.tcb_list, tcb);
- gio = g_io_channel_unix_new(tcb->evt_pipe[PIPE_READ]);
- if (!gio) {
- ErrPrint("Failed to get gio\n");
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- server_destroy(server);
- return FALSE;
- }
-
- g_io_channel_set_close_on_unref(gio, FALSE);
-
- tcb->id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_pipe_cb, tcb);
- if (tcb->id == 0) {
- GError *err = NULL;
- ErrPrint("Failed to add IO Watch\n");
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ gio = g_io_channel_unix_new(tcb->evt_pipe[PIPE_READ]);
+ if (!gio) {
+ ErrPrint("Failed to get gio\n");
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ server_destroy(server);
+ return FALSE;
+ }
+
+ g_io_channel_set_close_on_unref(gio, FALSE);
+
+ tcb->id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_pipe_cb, tcb);
+ if (tcb->id == 0) {
+ GError *err = NULL;
+ ErrPrint("Failed to add IO Watch\n");
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ server_destroy(server);
+ return FALSE;
}
g_io_channel_unref(gio);
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- server_destroy(server);
- return FALSE;
- }
- g_io_channel_unref(gio);
- invoke_con_cb_list(tcb->handle, tcb->handle, 0, NULL, 0);
+ invoke_con_cb_list(tcb->handle, tcb->handle, 0, NULL, 0);
- ret = pthread_attr_init(&attr);
- if (ret == 0) {
- pattr = &attr;
+ ret = pthread_attr_init(&attr);
+ if (ret == 0) {
+ pattr = &attr;
- ret = pthread_attr_setscope(pattr, PTHREAD_SCOPE_SYSTEM);
- if (ret != 0) {
- ErrPrint("setscope: %s\n", strerror(ret));
- }
+ ret = pthread_attr_setscope(pattr, PTHREAD_SCOPE_SYSTEM);
+ if (ret != 0) {
+ ErrPrint("setscope: %s\n", strerror(ret));
+ }
- ret = pthread_attr_setinheritsched(pattr, PTHREAD_EXPLICIT_SCHED);
+ ret = pthread_attr_setinheritsched(pattr, PTHREAD_EXPLICIT_SCHED);
+ if (ret != 0) {
+ ErrPrint("setinheritsched: %s\n", strerror(ret));
+ }
+ } else {
+ ErrPrint("attr_init: %s\n", strerror(ret));
+ }
+ ret = pthread_create(&tcb->thid, pattr, client_cb, tcb);
+ if (pattr) {
+ pthread_attr_destroy(pattr);
+ }
if (ret != 0) {
- ErrPrint("setinheritsched: %s\n", strerror(ret));
+ ErrPrint("Thread creation failed: %s\n", strerror(ret));
+ invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ server_destroy(server);
+ return FALSE;
}
- } else {
- ErrPrint("attr_init: %s\n", strerror(ret));
- }
- ret = pthread_create(&tcb->thid, pattr, client_cb, tcb);
- if (pattr) {
- pthread_attr_destroy(pattr);
- }
- if (ret != 0) {
- ErrPrint("Thread creation failed: %s\n", strerror(ret));
- invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- server_destroy(server);
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
/*!
@@ -686,152 +686,152 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer data)
*/
EAPI int com_core_thread_client_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
{
- GIOChannel *gio;
- int client_fd;
- struct tcb *tcb;
- int ret;
- pthread_attr_t attr;
- pthread_attr_t *pattr = NULL;
-
- client_fd = secure_socket_create_client(addr);
- if (client_fd < 0) {
- return client_fd;
- }
-
- if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
-
- if (fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("Error: %s\n", strerror(errno));
- }
-
- tcb = tcb_create(client_fd, is_sync, service_cb, data);
- if (!tcb) {
- ErrPrint("Failed to create a new TCB\n");
- secure_socket_destroy_handle(client_fd);
- return -EFAULT;
- }
-
- tcb->server_handle = -1;
-
- s_info.tcb_list = dlist_append(s_info.tcb_list, tcb);
-
- gio = g_io_channel_unix_new(tcb->evt_pipe[PIPE_READ]);
- if (!gio) {
- ErrPrint("Failed to get gio\n");
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- return -EIO;
- }
-
- g_io_channel_set_close_on_unref(gio, FALSE);
-
- tcb->id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_pipe_cb, tcb);
- if (tcb->id == 0) {
- GError *err = NULL;
- ErrPrint("Failed to add IO Watch\n");
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ GIOChannel *gio;
+ int client_fd;
+ struct tcb *tcb;
+ int ret;
+ pthread_attr_t attr;
+ pthread_attr_t *pattr = NULL;
+
+ client_fd = secure_socket_create_client(addr);
+ if (client_fd < 0) {
+ return client_fd;
+ }
+
+ if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
}
- g_io_channel_unref(gio);
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- return -EIO;
- }
- g_io_channel_unref(gio);
+ if (fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+
+ tcb = tcb_create(client_fd, is_sync, service_cb, data);
+ if (!tcb) {
+ ErrPrint("Failed to create a new TCB\n");
+ secure_socket_destroy_handle(client_fd);
+ return -EFAULT;
+ }
- invoke_con_cb_list(tcb->handle, tcb->handle, 0, NULL, 0);
+ tcb->server_handle = -1;
- ret = pthread_attr_init(&attr);
- if (ret == 0) {
- pattr = &attr;
+ s_info.tcb_list = dlist_append(s_info.tcb_list, tcb);
- ret = pthread_attr_setscope(pattr, PTHREAD_SCOPE_SYSTEM);
- if (ret != 0) {
- ErrPrint("setscope: %s\n", strerror(ret));
+ gio = g_io_channel_unix_new(tcb->evt_pipe[PIPE_READ]);
+ if (!gio) {
+ ErrPrint("Failed to get gio\n");
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ return -EIO;
}
- ret = pthread_attr_setinheritsched(pattr, PTHREAD_EXPLICIT_SCHED);
+ g_io_channel_set_close_on_unref(gio, FALSE);
+
+ tcb->id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_pipe_cb, tcb);
+ if (tcb->id == 0) {
+ GError *err = NULL;
+ ErrPrint("Failed to add IO Watch\n");
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ return -EIO;
+ }
+
+ g_io_channel_unref(gio);
+
+ invoke_con_cb_list(tcb->handle, tcb->handle, 0, NULL, 0);
+
+ ret = pthread_attr_init(&attr);
+ if (ret == 0) {
+ pattr = &attr;
+
+ ret = pthread_attr_setscope(pattr, PTHREAD_SCOPE_SYSTEM);
+ if (ret != 0) {
+ ErrPrint("setscope: %s\n", strerror(ret));
+ }
+
+ ret = pthread_attr_setinheritsched(pattr, PTHREAD_EXPLICIT_SCHED);
+ if (ret != 0) {
+ ErrPrint("setinheritsched: %s\n", strerror(ret));
+ }
+ } else {
+ ErrPrint("attr_init: %s\n", strerror(ret));
+ }
+ ret = pthread_create(&tcb->thid, pattr, client_cb, tcb);
+ if (pattr) {
+ pthread_attr_destroy(pattr);
+ }
if (ret != 0) {
- ErrPrint("setinheritsched: %s\n", strerror(ret));
+ ErrPrint("Thread creation failed: %s\n", strerror(ret));
+ invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
+ secure_socket_destroy_handle(tcb->handle);
+ tcb_destroy(tcb);
+ return -EFAULT;
}
- } else {
- ErrPrint("attr_init: %s\n", strerror(ret));
- }
- ret = pthread_create(&tcb->thid, pattr, client_cb, tcb);
- if (pattr) {
- pthread_attr_destroy(pattr);
- }
- if (ret != 0) {
- ErrPrint("Thread creation failed: %s\n", strerror(ret));
- invoke_disconn_cb_list(tcb->handle, 0, 0, 0);
- secure_socket_destroy_handle(tcb->handle);
- tcb_destroy(tcb);
- return -EFAULT;
- }
- return tcb->handle;
+ return tcb->handle;
}
/*!
* \NOTE
* Running thread: Main
*/
-EAPI int com_core_thread_server_create(const char *addr, int is_sync, int (*service_cb)(int fd, void *data), void *data)
+EAPI int com_core_thread_server_create(const char *addr, int is_sync, const char *label, int (*service_cb)(int fd, void *data), void *data)
{
- GIOChannel *gio;
- int fd;
- struct server *server;
-
- fd = secure_socket_create_server(addr);
- if (fd < 0) {
- return fd;
- }
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- ErrPrint("fcntl: %s\n", strerror(errno));
- }
-
- if (!is_sync && fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
- ErrPrint("fcntl: %s\n", strerror(errno));
- }
-
- server = server_create(fd, service_cb, data);
- if (!server) {
- secure_socket_destroy_handle(fd);
- return -ENOMEM;
- }
-
- DbgPrint("Create new IO channel for socket FD: %d\n", fd);
- gio = g_io_channel_unix_new(server->handle);
- if (!gio) {
- ErrPrint("Failed to create new io channel\n");
- server_destroy(server);
- return -EIO;
- }
-
- g_io_channel_set_close_on_unref(gio, FALSE);
-
- server->id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc)accept_cb, server);
- if (server->id == 0) {
- GError *err = NULL;
- ErrPrint("Failed to add IO watch\n");
- g_io_channel_shutdown(gio, TRUE, &err);
- if (err) {
- ErrPrint("Shutdown: %s\n", err->message);
- g_error_free(err);
+ GIOChannel *gio;
+ int fd;
+ struct server *server;
+
+ fd = secure_socket_create_server_with_permission(addr, label);
+ if (fd < 0) {
+ return fd;
+ }
+
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
+
+ if (!is_sync && fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
+
+ server = server_create(fd, service_cb, data);
+ if (!server) {
+ secure_socket_destroy_handle(fd);
+ return -ENOMEM;
+ }
+
+ DbgPrint("Create new IO channel for socket FD: %d\n", fd);
+ gio = g_io_channel_unix_new(server->handle);
+ if (!gio) {
+ ErrPrint("Failed to create new io channel\n");
+ server_destroy(server);
+ return -EIO;
+ }
+
+ g_io_channel_set_close_on_unref(gio, FALSE);
+
+ server->id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc)accept_cb, server);
+ if (server->id == 0) {
+ GError *err = NULL;
+ ErrPrint("Failed to add IO watch\n");
+ g_io_channel_shutdown(gio, TRUE, &err);
+ if (err) {
+ ErrPrint("Shutdown: %s\n", err->message);
+ g_error_free(err);
+ }
+ g_io_channel_unref(gio);
+ server_destroy(server);
+ return -EIO;
}
- g_io_channel_unref(gio);
- server_destroy(server);
- return -EIO;
- }
- g_io_channel_unref(gio);
- return server->handle;
+ g_io_channel_unref(gio);
+ return server->handle;
}
/*!
@@ -840,89 +840,89 @@ EAPI int com_core_thread_server_create(const char *addr, int is_sync, int (*serv
*/
static inline struct tcb *find_tcb_by_handle(int handle)
{
- struct dlist *l;
- struct tcb *tcb;
+ struct dlist *l;
+ struct tcb *tcb;
- dlist_foreach(s_info.tcb_list, l, tcb) {
- if (tcb->handle == handle) {
- return tcb;
+ dlist_foreach(s_info.tcb_list, l, tcb) {
+ if (tcb->handle == handle) {
+ return tcb;
+ }
}
- }
- return NULL;
+ return NULL;
}
EAPI int com_core_thread_send_with_fd(int handle, const char *buffer, int size, double timeout, int fd)
{
- int writesize;
- int ret;
- struct tcb *tcb;
+ int writesize;
+ int ret;
+ struct tcb *tcb;
- fd_set set;
+ fd_set set;
- tcb = find_tcb_by_handle(handle);
- if (!tcb) {
- ErrPrint("TCB is not found\n");
- return -EINVAL;
- }
+ tcb = find_tcb_by_handle(handle);
+ if (!tcb) {
+ ErrPrint("TCB is not found\n");
+ return -EINVAL;
+ }
- writesize = 0;
- while (size > 0) {
- FD_ZERO(&set);
- FD_SET(tcb->handle, &set);
+ writesize = 0;
+ while (size > 0) {
+ FD_ZERO(&set);
+ FD_SET(tcb->handle, &set);
- if (timeout > 0.0f) {
- struct timeval tv;
+ if (timeout > 0.0f) {
+ struct timeval tv;
- tv.tv_sec = (unsigned long)timeout;
- tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
+ tv.tv_sec = (unsigned long)timeout;
+ tv.tv_usec = (timeout - (unsigned long)timeout) * 1000000u;
- ret = select(tcb->handle + 1, NULL, &set, NULL, &tv);
- } else if (timeout == 0.0f) {
- ret = select(tcb->handle + 1, NULL, &set, NULL, NULL);
- } else {
- ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
- return -EINVAL;
- }
+ ret = select(tcb->handle + 1, NULL, &set, NULL, &tv);
+ } else if (timeout == 0.0f) {
+ ret = select(tcb->handle + 1, NULL, &set, NULL, NULL);
+ } else {
+ ErrPrint("Invalid timeout: %lf (it must be greater than 0.0)\n", timeout);
+ return -EINVAL;
+ }
- if (ret < 0) {
- ret = -errno;
- if (errno == EINTR) {
- DbgPrint("Select receives INTR\n");
- continue;
- }
-
- ErrPrint("Error: %s\n", strerror(errno));
- return ret;
- } else if (ret == 0) {
- ErrPrint("Timeout expired\n");
- break;
- }
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EINTR) {
+ DbgPrint("Select receives INTR\n");
+ continue;
+ }
+
+ ErrPrint("Error: %s\n", strerror(errno));
+ return ret;
+ } else if (ret == 0) {
+ ErrPrint("Timeout expired\n");
+ break;
+ }
- if (!FD_ISSET(tcb->handle, &set)) {
- ErrPrint("Unexpected handle is toggled\n");
- return -EINVAL;
- }
+ if (!FD_ISSET(tcb->handle, &set)) {
+ ErrPrint("Unexpected handle is toggled\n");
+ return -EINVAL;
+ }
- ret = secure_socket_send_with_fd(tcb->handle, buffer + writesize, size, fd);
- if (ret < 0) {
- if (ret == -EAGAIN) {
- DbgPrint("Retry to send data (%d:%d)\n", writesize, size);
- continue;
- }
- DbgPrint("Failed to send: %d\n", ret);
- return ret;
- } else if (ret == 0) {
- DbgPrint("Disconnected? : Send bytes: 0\n");
- return 0;
- }
+ ret = secure_socket_send_with_fd(tcb->handle, buffer + writesize, size, fd);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ DbgPrint("Retry to send data (%d:%d)\n", writesize, size);
+ continue;
+ }
+ DbgPrint("Failed to send: %d\n", ret);
+ return ret;
+ } else if (ret == 0) {
+ DbgPrint("Disconnected? : Send bytes: 0\n");
+ return 0;
+ }
- fd = -1; /* Send only once if it is fd */
- size -= ret;
- writesize += ret;
- }
+ fd = -1; /* Send only once if it is fd */
+ size -= ret;
+ writesize += ret;
+ }
- return writesize;
+ return writesize;
}
/*!
@@ -931,91 +931,91 @@ EAPI int com_core_thread_send_with_fd(int handle, const char *buffer, int size,
*/
EAPI int com_core_thread_send(int handle, const char *buffer, int size, double timeout)
{
- return com_core_thread_send_with_fd(handle, buffer, size, timeout, -1);
+ return com_core_thread_send_with_fd(handle, buffer, size, timeout, -1);
}
EAPI int com_core_thread_recv_with_fd(int handle, char *buffer, int size, int *sender_pid, double timeout, int *fd)
{
- int readsize;
- int ret;
- struct chunk *chunk;
- struct dlist *l;
- struct tcb *tcb;
- int _sender_pid;
- int _fd;
-
- tcb = find_tcb_by_handle(handle);
- if (!tcb) {
- ErrPrint("TCB is not exists\n");
- return -EINVAL;
- }
-
- if (!sender_pid) {
- sender_pid = &_sender_pid;
- }
-
- if (!fd) {
- fd = &_fd;
- }
-
- *fd = -1;
- readsize = 0;
- while (readsize < size) {
- l = dlist_nth(tcb->chunk_list, 0);
- chunk = dlist_data(l);
- /*!
- * \note
- * Pumping up the pipe data
- * This is the first time to use a chunk
- */
- if (!chunk) {
- ret = wait_event(tcb, timeout);
- if (ret == -EAGAIN) {
- /* Log is printed from wait_event */
- continue;
- } else if (ret == -ECONNRESET) {
- DbgPrint("Connection is lost\n");
- break;
- } else if (ret < 0) {
- /* Log is printed from wait_event */
- return ret;
- }
-
- l = dlist_nth(tcb->chunk_list, 0);
- chunk = dlist_data(l);
- if (!chunk) {
- char event_ch;
-
- /* Consuming the event */
- if (read(tcb->evt_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
- ErrPrint("Failed to get readsize: %s\n", strerror(errno));
- } else if (event_ch == EVENT_READY) {
- ErrPrint("Failed to get a new chunk\n");
- } else if (event_ch == EVENT_TERM) {
- DbgPrint("Disconnected\n");
- }
-
- break;
- }
+ int readsize;
+ int ret;
+ struct chunk *chunk;
+ struct dlist *l;
+ struct tcb *tcb;
+ int _sender_pid;
+ int _fd;
+
+ tcb = find_tcb_by_handle(handle);
+ if (!tcb) {
+ ErrPrint("TCB is not exists\n");
+ return -EINVAL;
}
- ret = chunk->size - chunk->offset;
- ret = ret > (size - readsize) ? (size - readsize) : ret;
- memcpy(buffer + readsize, chunk->data + chunk->offset, ret);
- readsize += ret;
- chunk->offset += ret;
+ if (!sender_pid) {
+ sender_pid = &_sender_pid;
+ }
- *sender_pid = chunk->pid;
- if (chunk->fd >= 0) {
- *fd = chunk->fd;
+ if (!fd) {
+ fd = &_fd;
}
- if (chunk->offset == chunk->size) {
- chunk_remove(tcb, chunk);
+ *fd = -1;
+ readsize = 0;
+ while (readsize < size) {
+ l = dlist_nth(tcb->chunk_list, 0);
+ chunk = dlist_data(l);
+ /*!
+ * \note
+ * Pumping up the pipe data
+ * This is the first time to use a chunk
+ */
+ if (!chunk) {
+ ret = wait_event(tcb, timeout);
+ if (ret == -EAGAIN) {
+ /* Log is printed from wait_event */
+ continue;
+ } else if (ret == -ECONNRESET) {
+ DbgPrint("Connection is lost\n");
+ break;
+ } else if (ret < 0) {
+ /* Log is printed from wait_event */
+ return ret;
+ }
+
+ l = dlist_nth(tcb->chunk_list, 0);
+ chunk = dlist_data(l);
+ if (!chunk) {
+ char event_ch;
+
+ /* Consuming the event */
+ if (read(tcb->evt_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
+ ErrPrint("Failed to get readsize: %s\n", strerror(errno));
+ } else if (event_ch == EVENT_READY) {
+ ErrPrint("Failed to get a new chunk\n");
+ } else if (event_ch == EVENT_TERM) {
+ DbgPrint("Disconnected\n");
+ }
+
+ break;
+ }
+ }
+
+ ret = chunk->size - chunk->offset;
+ ret = ret > (size - readsize) ? (size - readsize) : ret;
+ memcpy(buffer + readsize, chunk->data + chunk->offset, ret);
+ readsize += ret;
+ chunk->offset += ret;
+
+ *sender_pid = chunk->pid;
+ if (chunk->fd >= 0) {
+ *fd = chunk->fd;
+ }
+
+ if (chunk->offset == chunk->size) {
+ chunk_remove(tcb, chunk);
+ }
}
- }
- return readsize;
+ return readsize;
}
/*!
@@ -1024,7 +1024,7 @@ EAPI int com_core_thread_recv_with_fd(int handle, char *buffer, int size, int *s
*/
EAPI int com_core_thread_recv(int handle, char *buffer, int size, int *sender_pid, double timeout)
{
- return com_core_thread_recv_with_fd(handle, buffer, size, sender_pid, timeout, NULL);
+ return com_core_thread_recv_with_fd(handle, buffer, size, sender_pid, timeout, NULL);
}
/*!
@@ -1033,33 +1033,33 @@ EAPI int com_core_thread_recv(int handle, char *buffer, int size, int *sender_pi
*/
EAPI int com_core_thread_server_destroy(int handle)
{
- struct dlist *l;
- struct dlist *n;
- struct tcb *tcb;
- struct server *server;
-
- dlist_foreach_safe(s_info.tcb_list, l, n, tcb) {
- if (tcb->server_handle != handle) {
- continue;
+ struct dlist *l;
+ struct dlist *n;
+ struct tcb *tcb;
+ struct server *server;
+
+ dlist_foreach_safe(s_info.tcb_list, l, n, tcb) {
+ if (tcb->server_handle != handle) {
+ continue;
+ }
+
+ invoke_disconn_cb_list(handle, 0, 0, 0);
+ terminate_thread(tcb);
+ tcb_destroy(tcb);
+ return 0;
}
- invoke_disconn_cb_list(handle, 0, 0, 0);
- terminate_thread(tcb);
- tcb_destroy(tcb);
- return 0;
- }
+ dlist_foreach_safe(s_info.server_list, l, n, server) {
+ if (server->handle != handle) {
+ continue;
+ }
- dlist_foreach_safe(s_info.server_list, l, n, server) {
- if (server->handle != handle) {
- continue;
+ invoke_disconn_cb_list(handle, 0, 0, 0);
+ server_destroy(server);
+ return 0;
}
- invoke_disconn_cb_list(handle, 0, 0, 0);
- server_destroy(server);
- return 0;
- }
-
- return -ENOENT;
+ return -ENOENT;
}
/*!
@@ -1068,17 +1068,17 @@ EAPI int com_core_thread_server_destroy(int handle)
*/
EAPI int com_core_thread_client_destroy(int handle)
{
- struct tcb *tcb;
+ struct tcb *tcb;
- tcb = find_tcb_by_handle(handle);
- if (!tcb) {
- return -ENOENT;
- }
+ tcb = find_tcb_by_handle(handle);
+ if (!tcb) {
+ return -ENOENT;
+ }
- invoke_disconn_cb_list(handle, 0, 0, 0);
- terminate_thread(tcb);
- tcb_destroy(tcb);
- return 0;
+ invoke_disconn_cb_list(handle, 0, 0, 0);
+ terminate_thread(tcb);
+ tcb_destroy(tcb);
+ return 0;
}
/* End of a file */
diff --git a/src/dlist.c b/src/dlist.c
index 695d22a..f4af25e 100644
--- a/src/dlist.c
+++ b/src/dlist.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/packet.c b/src/packet.c
index 0c29d50..edf3158 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#include <stdio.h>
#include <stdarg.h>
@@ -31,603 +31,603 @@
int errno;
struct data {
- struct {
- int version;
- int payload_size;
- char command[PACKET_MAX_CMD];
- enum packet_type type;
- enum packet_flag flag;
- double seq;
- unsigned long source;
- unsigned long destination;
- unsigned long mask;
- int fd;
- } head;
-
- char payload[];
+ struct {
+ int version;
+ int payload_size;
+ char command[PACKET_MAX_CMD];
+ enum packet_type type;
+ enum packet_flag flag;
+ double seq;
+ unsigned long source;
+ unsigned long destination;
+ unsigned long mask;
+ int fd;
+ } head;
+
+ char payload[];
};
struct packet {
- enum {
- VALID = 0xbeefbeef,
- INVALID = 0xdeaddead
- } state;
- int refcnt;
- struct data *data;
+ enum {
+ VALID = 0xbeefbeef,
+ INVALID = 0xdeaddead
+ } state;
+ int refcnt;
+ struct data *data;
};
EAPI const enum packet_type const packet_type(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_ERROR;
+ }
- return packet->data->head.type;
+ return packet->data->head.type;
}
EAPI unsigned long packet_mask(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.mask;
+ return packet->data->head.mask;
}
EAPI int packet_set_mask(struct packet *packet, unsigned long mask)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- packet->data->head.mask = mask;
- return 0;
+ packet->data->head.mask = mask;
+ return 0;
}
EAPI const enum packet_flag const packet_flag(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_FLAG_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_FLAG_ERROR;
+ }
- return packet->data->head.flag;
+ return packet->data->head.flag;
}
EAPI int packet_set_flag(struct packet *packet, enum packet_flag flag)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- packet->data->head.flag = flag;
- return 0;
+ packet->data->head.flag = flag;
+ return 0;
}
EAPI const unsigned long const packet_source(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.source;
+ return packet->data->head.source;
}
EAPI int packet_set_source(struct packet *packet, unsigned long source)
{
- if (!packet || packet->state != VALID || !packet->data || !source) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data || !source) {
+ return -EINVAL;
+ }
- packet->data->head.source = source;
- return 0;
+ packet->data->head.source = source;
+ return 0;
}
EAPI int packet_set_fd(struct packet *packet, int fd)
{
- if (!packet || packet->state != VALID || !packet->data || fd < 0) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data || fd < 0) {
+ return -EINVAL;
+ }
- packet->data->head.fd = fd;
- return 0;
+ packet->data->head.fd = fd;
+ return 0;
}
EAPI int packet_fd(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- return packet->data->head.fd;
+ return packet->data->head.fd;
}
EAPI const unsigned long const packet_destination(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.destination;
+ return packet->data->head.destination;
}
EAPI int packet_set_destination(struct packet *packet, unsigned long destination)
{
- if (!packet || packet->state != VALID || !packet->data || !destination) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data || !destination) {
+ return -EINVAL;
+ }
- packet->data->head.destination = destination;
- return 0;
+ packet->data->head.destination = destination;
+ return 0;
}
EAPI const int const packet_version(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_ERROR;
+ }
- return packet->data->head.version;
+ return packet->data->head.version;
}
EAPI const int const packet_header_size(void)
{
- struct data payload; /* Only for getting the size of header of packet */
+ struct data payload; /* Only for getting the size of header of packet */
- return sizeof(payload.head);
+ return sizeof(payload.head);
}
EAPI const int const packet_size(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- return sizeof(*packet->data) + packet->data->head.payload_size;
+ return sizeof(*packet->data) + packet->data->head.payload_size;
}
EAPI const double const packet_seq(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.seq;
+ return packet->data->head.seq;
}
EAPI const int const packet_payload_size(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- return packet->data->head.payload_size;
+ return packet->data->head.payload_size;
}
EAPI const char * const packet_command(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return NULL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return NULL;
+ }
- return packet->data->head.command;
+ return packet->data->head.command;
}
EAPI const void * const packet_data(const struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
- return packet->data;
+ return packet->data;
}
static inline __attribute__((always_inline)) struct data *check_and_expand_packet(struct data *packet, int *payload_size)
{
- struct data *new_packet;
+ struct data *new_packet;
- if (packet->head.payload_size < *payload_size) {
- return packet;
- }
+ if (packet->head.payload_size < *payload_size) {
+ return packet;
+ }
- new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
- if (!new_packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- free(packet);
- return NULL;
- }
+ new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
+ if (!new_packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(packet);
+ return NULL;
+ }
- *payload_size += BUFSIZ;
- return new_packet;
+ *payload_size += BUFSIZ;
+ return new_packet;
}
static inline struct packet *packet_body_filler(struct packet *packet, int payload_size, const char *ptr, va_list va)
{
- char *payload;
- char *str;
-
- while (*ptr) {
- payload = packet->data->payload + packet->data->head.payload_size;
-
- switch (*ptr) {
- case 'i':
- case 'I':
- packet->data->head.payload_size += sizeof(int);
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- *((int *)payload) = (int)va_arg(va, int);
- break;
- case 's':
- case 'S':
- str = (char *)va_arg(va, char *);
-
- if (str) {
- packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- strcpy(payload, str); /*!< Including NIL */
- } else {
- packet->data->head.payload_size += 1;
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
+ char *payload;
+ char *str;
+
+ while (*ptr) {
+ payload = packet->data->payload + packet->data->head.payload_size;
+
+ switch (*ptr) {
+ case 'i':
+ case 'I':
+ packet->data->head.payload_size += sizeof(int);
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ *((int *)payload) = (int)va_arg(va, int);
+ break;
+ case 's':
+ case 'S':
+ str = (char *)va_arg(va, char *);
+
+ if (str) {
+ packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ strcpy(payload, str); /*!< Including NIL */
+ } else {
+ packet->data->head.payload_size += 1;
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ payload[0] = '\0';
+ }
+ break;
+ case 'd':
+ case 'D':
+ packet->data->head.payload_size += sizeof(double);
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ *((double *)payload) = (double)va_arg(va, double);
+ break;
+ default:
+ ErrPrint("Invalid type [%c]\n", *ptr);
packet->state = INVALID;
+ free(packet->data);
free(packet);
packet = NULL;
goto out;
- }
-
- payload[0] = '\0';
- }
- break;
- case 'd':
- case 'D':
- packet->data->head.payload_size += sizeof(double);
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
}
- *((double *)payload) = (double)va_arg(va, double);
- break;
- default:
- ErrPrint("Invalid type [%c]\n", *ptr);
- packet->state = INVALID;
- free(packet->data);
- free(packet);
- packet = NULL;
- goto out;
+ ptr++;
}
- ptr++;
- }
-
out:
- return packet;
+ return packet;
}
EAPI struct packet *packet_create_reply(const struct packet *packet, const char *fmt, ...)
{
- int payload_size;
- struct packet *result;
- va_list va;
-
- if (!packet || packet->state != VALID) {
- return NULL;
- }
-
- result = malloc(sizeof(*result));
- if (!result) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*result->data) + BUFSIZ;
- result->refcnt = 0;
- result->data = calloc(1, BUFSIZ);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- result->state = INVALID;
- free(result);
- return NULL;
- }
-
- result->state = VALID;
- result->data->head.source = packet->data->head.destination;
- result->data->head.destination = packet->data->head.source;
- result->data->head.mask = 0xFFFFFFFF;
-
- result->data->head.seq = packet->data->head.seq;
- result->data->head.type = PACKET_ACK;
- result->data->head.version = packet->data->head.version;
- result->data->head.fd = -1;
- if (packet->data->head.command[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)result->data->head.command;
- unsigned int *packet_cmd = (unsigned int *)packet->data->head.command;
-
- *head_cmd = *packet_cmd;
- } else {
- strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
- }
- result->data->head.payload_size = 0;
- payload_size -= sizeof(*result->data);
-
- va_start(va, fmt);
- result = packet_body_filler(result, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(result);
+ int payload_size;
+ struct packet *result;
+ va_list va;
+
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
+
+ result = malloc(sizeof(*result));
+ if (!result) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*result->data) + BUFSIZ;
+ result->refcnt = 0;
+ result->data = calloc(1, BUFSIZ);
+ if (!result->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ result->state = INVALID;
+ free(result);
+ return NULL;
+ }
+
+ result->state = VALID;
+ result->data->head.source = packet->data->head.destination;
+ result->data->head.destination = packet->data->head.source;
+ result->data->head.mask = 0xFFFFFFFF;
+
+ result->data->head.seq = packet->data->head.seq;
+ result->data->head.type = PACKET_ACK;
+ result->data->head.version = packet->data->head.version;
+ result->data->head.fd = -1;
+ if (packet->data->head.command[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)result->data->head.command;
+ unsigned int *packet_cmd = (unsigned int *)packet->data->head.command;
+
+ *head_cmd = *packet_cmd;
+ } else {
+ strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
+ }
+ result->data->head.payload_size = 0;
+ payload_size -= sizeof(*result->data);
+
+ va_start(va, fmt);
+ result = packet_body_filler(result, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(result);
}
EAPI int packet_swap_address(struct packet *packet)
{
- unsigned long tmp;
+ unsigned long tmp;
- if (!packet || packet->state != VALID) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID) {
+ return -EINVAL;
+ }
- tmp = packet->data->head.source;
- packet->data->head.source = packet->data->head.destination;
- packet->data->head.destination = tmp;
+ tmp = packet->data->head.source;
+ packet->data->head.source = packet->data->head.destination;
+ packet->data->head.destination = tmp;
- return 0;
+ return 0;
}
EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
{
- struct packet *packet;
- int payload_size;
- va_list va;
-
- if (strlen(cmd) >= PACKET_MAX_CMD) {
- ErrPrint("Command is too long\n");
- return NULL;
- }
-
- packet = malloc(sizeof(*packet));
- if (!packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*packet->data) + BUFSIZ;
- packet->refcnt = 0;
- packet->data = calloc(1, BUFSIZ);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet);
- return NULL;
- }
-
- packet->state = VALID;
- packet->data->head.source = 0lu;
- packet->data->head.destination = 0lu;
- packet->data->head.mask = 0xFFFFFFFF;
- packet->data->head.seq = util_timestamp();
- packet->data->head.type = PACKET_REQ;
- packet->data->head.version = PACKET_VERSION;
- packet->data->head.fd = -1;
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)packet->data->head.command;
- unsigned int *in_cmd = (unsigned int *)cmd;
-
- *head_cmd = *in_cmd;
- } else {
- strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
- }
- packet->data->head.payload_size = 0;
- payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
-
- va_start(va, fmt);
- packet = packet_body_filler(packet, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(packet);
+ struct packet *packet;
+ int payload_size;
+ va_list va;
+
+ if (strlen(cmd) >= PACKET_MAX_CMD) {
+ ErrPrint("Command is too long\n");
+ return NULL;
+ }
+
+ packet = malloc(sizeof(*packet));
+ if (!packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*packet->data) + BUFSIZ;
+ packet->refcnt = 0;
+ packet->data = calloc(1, BUFSIZ);
+ if (!packet->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet);
+ return NULL;
+ }
+
+ packet->state = VALID;
+ packet->data->head.source = 0lu;
+ packet->data->head.destination = 0lu;
+ packet->data->head.mask = 0xFFFFFFFF;
+ packet->data->head.seq = util_timestamp();
+ packet->data->head.type = PACKET_REQ;
+ packet->data->head.version = PACKET_VERSION;
+ packet->data->head.fd = -1;
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)packet->data->head.command;
+ unsigned int *in_cmd = (unsigned int *)cmd;
+
+ *head_cmd = *in_cmd;
+ } else {
+ strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
+ }
+ packet->data->head.payload_size = 0;
+ payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
+
+ va_start(va, fmt);
+ packet = packet_body_filler(packet, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(packet);
}
EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
{
- int payload_size;
- struct packet *result;
- va_list va;
-
- if (strlen(cmd) >= PACKET_MAX_CMD) {
- ErrPrint("Command is too long\n");
- return NULL;
- }
-
- result = malloc(sizeof(*result));
- if (!result) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*result->data) + BUFSIZ;
- result->refcnt = 0;
- result->data = calloc(1, BUFSIZ);
- if (!result->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- result->state = INVALID;
- free(result);
- return NULL;
- }
-
- result->state = VALID;
- result->data->head.source = 0lu;
- result->data->head.destination = 0lu;
- result->data->head.mask = 0xFFFFFFFF;
- result->data->head.seq = util_timestamp();
- result->data->head.type = PACKET_REQ_NOACK;
- result->data->head.version = PACKET_VERSION;
- result->data->head.fd = -1;
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)result->data->head.command;
- unsigned int *cmd_in = (unsigned int *)cmd;
- *head_cmd = *cmd_in;
- } else {
- strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
- }
- result->data->head.payload_size = 0;
- payload_size -= sizeof(*result->data);
-
- va_start(va, fmt);
- result = packet_body_filler(result, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(result);
+ int payload_size;
+ struct packet *result;
+ va_list va;
+
+ if (strlen(cmd) >= PACKET_MAX_CMD) {
+ ErrPrint("Command is too long\n");
+ return NULL;
+ }
+
+ result = malloc(sizeof(*result));
+ if (!result) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*result->data) + BUFSIZ;
+ result->refcnt = 0;
+ result->data = calloc(1, BUFSIZ);
+ if (!result->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ result->state = INVALID;
+ free(result);
+ return NULL;
+ }
+
+ result->state = VALID;
+ result->data->head.source = 0lu;
+ result->data->head.destination = 0lu;
+ result->data->head.mask = 0xFFFFFFFF;
+ result->data->head.seq = util_timestamp();
+ result->data->head.type = PACKET_REQ_NOACK;
+ result->data->head.version = PACKET_VERSION;
+ result->data->head.fd = -1;
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)result->data->head.command;
+ unsigned int *cmd_in = (unsigned int *)cmd;
+ *head_cmd = *cmd_in;
+ } else {
+ strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
+ }
+ result->data->head.payload_size = 0;
+ payload_size -= sizeof(*result->data);
+
+ va_start(va, fmt);
+ result = packet_body_filler(result, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(result);
}
EAPI int packet_get(const struct packet *packet, const char *fmt, ...)
{
- const char *ptr;
- va_list va;
- int ret = 0;
- char *payload;
- int offset = 0;
- int *int_ptr;
- double *double_ptr;
- char **str_ptr;
-
- if (!packet || packet->state != VALID) {
- return -EINVAL;
- }
-
- va_start(va, fmt);
-
- ptr = fmt;
- while (*ptr && offset < packet->data->head.payload_size) {
- payload = packet->data->payload + offset;
- switch (*ptr) {
- case 'i':
- case 'I':
- int_ptr = (int *)va_arg(va, int *);
- *int_ptr = *((int *)payload);
- offset += sizeof(int);
- ret++;
- break;
- case 'd':
- case 'D':
- double_ptr = (double *)va_arg(va, double *);
- *double_ptr = *((double *)payload);
- offset += sizeof(double);
- ret++;
- break;
- case 's':
- case 'S':
- str_ptr = (char **)va_arg(va, char **);
- *str_ptr = payload;
- offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
- ret++;
- break;
- default:
- ret = -EINVAL;
- goto out;
- }
- ptr++;
- }
+ const char *ptr;
+ va_list va;
+ int ret = 0;
+ char *payload;
+ int offset = 0;
+ int *int_ptr;
+ double *double_ptr;
+ char **str_ptr;
+
+ if (!packet || packet->state != VALID) {
+ return -EINVAL;
+ }
+
+ va_start(va, fmt);
+
+ ptr = fmt;
+ while (*ptr && offset < packet->data->head.payload_size) {
+ payload = packet->data->payload + offset;
+ switch (*ptr) {
+ case 'i':
+ case 'I':
+ int_ptr = (int *)va_arg(va, int *);
+ *int_ptr = *((int *)payload);
+ offset += sizeof(int);
+ ret++;
+ break;
+ case 'd':
+ case 'D':
+ double_ptr = (double *)va_arg(va, double *);
+ *double_ptr = *((double *)payload);
+ offset += sizeof(double);
+ ret++;
+ break;
+ case 's':
+ case 'S':
+ str_ptr = (char **)va_arg(va, char **);
+ *str_ptr = payload;
+ offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
+ ret++;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
+ ptr++;
+ }
out:
- va_end(va);
- return ret;
+ va_end(va);
+ return ret;
}
EAPI struct packet *packet_ref(struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
- packet->refcnt++;
- return packet;
+ packet->refcnt++;
+ return packet;
}
EAPI struct packet *packet_unref(struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
-
- packet->refcnt--;
- if (packet->refcnt < 0) {
- ErrPrint("Invalid refcnt\n");
- return NULL;
- }
-
- if (packet->refcnt == 0) {
- packet->state = INVALID;
- free(packet->data);
- free(packet);
- return NULL;
- }
-
- return packet;
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
+
+ packet->refcnt--;
+ if (packet->refcnt < 0) {
+ ErrPrint("Invalid refcnt\n");
+ return NULL;
+ }
+
+ if (packet->refcnt == 0) {
+ packet->state = INVALID;
+ free(packet->data);
+ free(packet);
+ return NULL;
+ }
+
+ return packet;
}
EAPI int packet_destroy(struct packet *packet)
{
- packet_unref(packet);
- return 0;
+ packet_unref(packet);
+ return 0;
}
EAPI struct packet *packet_build(struct packet *packet, int offset, void *data, int size)
{
- char *ptr;
+ char *ptr;
- if (packet == NULL) {
- if (offset) {
- ErrPrint("Invalid argument\n");
- return NULL;
- }
+ if (packet == NULL) {
+ if (offset) {
+ ErrPrint("Invalid argument\n");
+ return NULL;
+ }
- packet = malloc(sizeof(*packet));
- if (!packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
+ packet = malloc(sizeof(*packet));
+ if (!packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
- packet->refcnt = 1;
- packet->data = calloc(1, size);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet);
- return NULL;
- }
+ packet->refcnt = 1;
+ packet->data = calloc(1, size);
+ if (!packet->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet);
+ return NULL;
+ }
- packet->state = VALID;
- memcpy(packet->data, data, size);
- packet->data->head.mask = 0xFFFFFFFF;
- return packet;
- }
+ packet->state = VALID;
+ memcpy(packet->data, data, size);
+ packet->data->head.mask = 0xFFFFFFFF;
+ return packet;
+ }
- ptr = realloc(packet->data, offset + size);
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet->data);
- free(packet);
- return NULL;
- }
+ ptr = realloc(packet->data, offset + size);
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet->data);
+ free(packet);
+ return NULL;
+ }
- packet->data = (struct data *)ptr;
- memcpy(ptr + offset, data, size);
+ packet->data = (struct data *)ptr;
+ memcpy(ptr + offset, data, size);
- return packet;
+ return packet;
}
/* End of a file */
diff --git a/src/secure_socket.c b/src/secure_socket.c
index a299b50..9138bf7 100644
--- a/src/secure_socket.c
+++ b/src/secure_socket.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#define _GNU_SOURCE
#include <stdio.h>
@@ -30,7 +30,7 @@
#include <errno.h>
#include <stdlib.h>
#include <systemd/sd-daemon.h>
-
+#include <attr/xattr.h>
#include <dlog.h>
#include "secure_socket.h"
@@ -42,517 +42,533 @@
#define RCVBUF_SZ 524288 /*!< 512 KB, this will be doubled by kernel */
enum scheme {
- SCHEME_LOCAL = 0x00,
- SCHEME_REMOTE = 0x01,
- SCHEME_UNKNOWN = 0x02,
+ SCHEME_LOCAL = 0x00,
+ SCHEME_REMOTE = 0x01,
+ SCHEME_UNKNOWN = 0x02,
};
struct function_table {
- int type;
- int (*create_socket)(const char *peer, int port, struct sockaddr *addr);
- int (*setup_handle)(int handle);
+ int type;
+ int (*create_socket)(const char *peer, int port, struct sockaddr *addr);
+ int (*setup_handle)(int handle);
};
int errno;
static inline int create_unix_socket(const char *peer, int port, struct sockaddr *addr)
{
- int len;
- int handle;
- struct sockaddr_un *un_addr = (struct sockaddr_un *)addr;
-
- len = sizeof(*un_addr);
- bzero(un_addr, len);
-
- if (strlen(peer) >= sizeof(un_addr->sun_path)) {
- ErrPrint("peer %s is too long to remember it\\n", peer);
- return -1;
- }
-
- /* We can believe this has no prob, because
- * we already check the size of add.rsun_path
- */
- strcpy(un_addr->sun_path, peer);
- un_addr->sun_family = AF_UNIX;
-
- handle = socket(PF_UNIX, SOCK_STREAM, 0);
- if (handle < 0) {
- handle = -errno;
- ErrPrint("Failed to create a socket %s\n", strerror(errno));
- }
-
- return handle;
+ int len;
+ int handle;
+ struct sockaddr_un *un_addr = (struct sockaddr_un *)addr;
+
+ len = sizeof(*un_addr);
+ bzero(un_addr, len);
+
+ if (strlen(peer) >= sizeof(un_addr->sun_path)) {
+ ErrPrint("peer %s is too long to remember it\\n", peer);
+ return -1;
+ }
+
+ /* We can believe this has no prob, because
+ * we already check the size of add.rsun_path
+ */
+ strcpy(un_addr->sun_path, peer);
+ un_addr->sun_family = AF_UNIX;
+
+ handle = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (handle < 0) {
+ handle = -errno;
+ ErrPrint("Failed to create a socket %s\n", strerror(errno));
+ }
+
+ return handle;
}
static inline int create_inet_socket(const char *peer, int port, struct sockaddr *addr)
{
- int handle;
- struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
-
- bzero(in_addr, sizeof(*in_addr));
-
- in_addr->sin_port = htons(port);
- in_addr->sin_family = AF_INET;
- if (*peer == '\0') {
- in_addr->sin_addr.s_addr = htonl(INADDR_ANY);
- } else {
- in_addr->sin_addr.s_addr = inet_addr(peer);
- }
-
- handle = socket(AF_INET, SOCK_STREAM, 0);
- if (handle < 0) {
- handle = -errno;
- ErrPrint("socket: %s\n", strerror(errno));
- }
-
- return handle;
+ int handle;
+ struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
+
+ bzero(in_addr, sizeof(*in_addr));
+
+ in_addr->sin_port = htons(port);
+ in_addr->sin_family = AF_INET;
+ if (*peer == '\0') {
+ in_addr->sin_addr.s_addr = htonl(INADDR_ANY);
+ } else {
+ in_addr->sin_addr.s_addr = inet_addr(peer);
+ }
+
+ handle = socket(AF_INET, SOCK_STREAM, 0);
+ if (handle < 0) {
+ handle = -errno;
+ ErrPrint("socket: %s\n", strerror(errno));
+ }
+
+ return handle;
}
static inline int create_systemd_socket(const char *peer, int port, struct sockaddr *addr)
{
- int handle = -1;
- int cnt;
-
- cnt = sd_listen_fds(0);
- if (cnt > 1) {
- ErrPrint("To many file descriptors are received on socket activation: %d\n", cnt);
- } else if (cnt == 1) {
- handle = SD_LISTEN_FDS_START + 0;
- } else {
- handle = create_inet_socket(peer, port, addr);
- }
-
- return handle;
+ int handle = -1;
+ int cnt;
+
+ cnt = sd_listen_fds(0);
+ if (cnt > 1) {
+ ErrPrint("To many file descriptors are received on socket activation: %d\n", cnt);
+ } else if (cnt == 1) {
+ handle = SD_LISTEN_FDS_START + 0;
+ } else {
+ handle = create_inet_socket(peer, port, addr);
+ }
+
+ return handle;
}
static inline int setup_unix_handle(int handle)
{
- int on = 1;
- int sndbuf = SNDBUF_SZ;
- int rcvbuf = RCVBUF_SZ;
-
- if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
- int ret;
- ret = -errno;
- ErrPrint("Failed to change sock opt : %s\n", strerror(errno));
- return ret;
- }
+ int on = 1;
+ int sndbuf = SNDBUF_SZ;
+ int rcvbuf = RCVBUF_SZ;
+
+ if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
+ int ret;
+ ret = -errno;
+ ErrPrint("Failed to change sock opt : %s\n", strerror(errno));
+ return ret;
+ }
- (void)setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- (void)setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
- (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
+ (void)setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ (void)setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
+ (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
- return 0;
+ return 0;
}
static inline int setup_inet_handle(int handle)
{
- int on = 1;
+ int on = 1;
- (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
+ (void)setsockopt(handle, IPPROTO_IP, TCP_NODELAY, &on, sizeof(on));
- return 0;
+ return 0;
}
static inline char *parse_scheme(const char *peer, int *port, struct function_table *vtable)
{
- int _port;
- char *addr = NULL;
-
- if (!port)
- port = &_port;
-
- *port = 0;
-
- if (!strncasecmp(peer, COM_CORE_LOCAL_SCHEME, COM_CORE_LOCAL_SCHEME_LEN)) {
- vtable->type = (int)SCHEME_LOCAL;
- peer += COM_CORE_LOCAL_SCHEME_LEN;
-
- addr = strdup(peer);
- if (!addr) {
- ErrPrint("Heap: %s\n", strerror(errno));
+ int _port;
+ char *addr = NULL;
+
+ if (!port)
+ port = &_port;
+
+ *port = 0;
+
+ if (!strncasecmp(peer, COM_CORE_LOCAL_SCHEME, COM_CORE_LOCAL_SCHEME_LEN)) {
+ vtable->type = (int)SCHEME_LOCAL;
+ peer += COM_CORE_LOCAL_SCHEME_LEN;
+
+ addr = strdup(peer);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+
+ vtable->create_socket = create_unix_socket;
+ vtable->setup_handle = setup_unix_handle;
+ } else if (!strncasecmp(peer, COM_CORE_SD_LOCAL_SCHEME, COM_CORE_SD_LOCAL_SCHEME_LEN)) {
+ vtable->type = (int)SCHEME_LOCAL;
+ peer += COM_CORE_SD_LOCAL_SCHEME_LEN;
+
+ addr = strdup(peer);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+
+ vtable->create_socket = create_systemd_socket;
+ vtable->setup_handle = setup_unix_handle;
+ } else if (!strncasecmp(peer, COM_CORE_REMOTE_SCHEME, COM_CORE_REMOTE_SCHEME_LEN)) {
+ register int len;
+ char *endptr;
+
+ vtable->type = (int)SCHEME_REMOTE;
+ peer += COM_CORE_REMOTE_SCHEME_LEN;
+
+ for (len = 0; peer[len] && peer[len] != ':'; len++);
+ if (peer[len] != ':') {
+ ErrPrint("Invalid syntax: %s\n", peer);
+ goto out;
+ }
+
+ addr = malloc(len + 1);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ goto out;
+ }
+
+ if (len > 0) {
+ strncpy(addr, peer, len);
+ }
+
+ addr[len] = '\0';
+
+ peer += len + 1;
+ *port = strtoul(peer, &endptr, 10);
+ if (*endptr != '\0' || peer == endptr) {
+ ErrPrint("Invalid: %s[%d]\n", peer - len - 1, len + 1);
+ free(addr);
+ addr = NULL;
+ goto out;
+ }
+
+ vtable->create_socket = create_inet_socket;
+ vtable->setup_handle = setup_inet_handle;
+ } else {
+ /* Fallback to local scheme */
+ vtable->type = (int)SCHEME_LOCAL;
+ addr = strdup(peer);
+ if (!addr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ goto out;
+ }
+
+ vtable->create_socket = create_unix_socket;
+ vtable->setup_handle = setup_unix_handle;
}
- vtable->create_socket = create_unix_socket;
- vtable->setup_handle = setup_unix_handle;
- } else if (!strncasecmp(peer, COM_CORE_SD_LOCAL_SCHEME, COM_CORE_SD_LOCAL_SCHEME_LEN)) {
- vtable->type = (int)SCHEME_LOCAL;
- peer += COM_CORE_SD_LOCAL_SCHEME_LEN;
+out:
+ return addr;
+}
- addr = strdup(peer);
+EAPI int secure_socket_create_client(const char *peer)
+{
+ int port;
+ char *addr;
+ int ret;
+ struct function_table vtable;
+ struct sockaddr *sockaddr;
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ int handle;
+ int addrlen;
+
+ addr = parse_scheme(peer, &port, &vtable);
if (!addr) {
- ErrPrint("Heap: %s\n", strerror(errno));
+ ErrPrint("peer: [%s] is not valid\n", peer);
+ return -EINVAL;
}
- vtable->create_socket = create_systemd_socket;
- vtable->setup_handle = setup_unix_handle;
- } else if (!strncasecmp(peer, COM_CORE_REMOTE_SCHEME, COM_CORE_REMOTE_SCHEME_LEN)) {
- register int len;
- char *endptr;
-
- vtable->type = (int)SCHEME_REMOTE;
- peer += COM_CORE_REMOTE_SCHEME_LEN;
-
- for (len = 0; peer[len] && peer[len] != ':'; len++);
- if (peer[len] != ':') {
- ErrPrint("Invalid syntax: %s\n", peer);
- goto out;
+ switch (vtable.type) {
+ case SCHEME_LOCAL:
+ sockaddr = (struct sockaddr *)&un_addr;
+ addrlen = sizeof(un_addr);
+ break;
+ case SCHEME_REMOTE:
+ sockaddr = (struct sockaddr *)&in_addr;
+ addrlen = sizeof(in_addr);
+ break;
+ default:
+ free(addr);
+ return -EINVAL;
}
- addr = malloc(len + 1);
- if (!addr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- goto out;
+ handle = vtable.create_socket(addr, port, sockaddr);
+ free(addr);
+ if (handle < 0) {
+ return handle;
}
- if (len > 0) {
- strncpy(addr, peer, len);
+ ret = connect(handle, sockaddr, addrlen);
+ if (ret < 0) {
+ ret = -errno;
+ ErrPrint("Failed to connect to server [%s] %s\n",
+ peer, strerror(errno));
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+
+ return ret;
}
- addr[len] = '\0';
+ ret = vtable.setup_handle(handle);
+ if (ret < 0) {
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
- peer += len + 1;
- *port = strtoul(peer, &endptr, 10);
- if (*endptr != '\0' || peer == endptr) {
- ErrPrint("Invalid: %s[%d]\n", peer - len - 1, len + 1);
- free(addr);
- addr = NULL;
- goto out;
+ return ret;
}
- vtable->create_socket = create_inet_socket;
- vtable->setup_handle = setup_inet_handle;
- } else {
- /* Fallback to local scheme */
- vtable->type = (int)SCHEME_LOCAL;
- addr = strdup(peer);
- if (!addr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- goto out;
- }
-
- vtable->create_socket = create_unix_socket;
- vtable->setup_handle = setup_unix_handle;
- }
+ return handle;
+}
-out:
- return addr;
+EAPI int secure_socket_create_server(const char *peer)
+{
+ return secure_socket_create_server_with_permission(peer, NULL);
}
-EAPI int secure_socket_create_client(const char *peer)
+EAPI int secure_socket_create_server_with_permission(const char *peer, const char *label)
{
- int port;
- char *addr;
- int ret;
- struct function_table vtable;
- struct sockaddr *sockaddr;
- struct sockaddr_in in_addr;
- struct sockaddr_un un_addr;
- int handle;
- int addrlen;
-
- addr = parse_scheme(peer, &port, &vtable);
- if (!addr) {
- ErrPrint("peer: [%s] is not valid\n", peer);
- return -EINVAL;
- }
-
- switch (vtable.type) {
+ int port;
+ char *addr;
+ int handle;
+ int ret;
+ struct sockaddr *sockaddr;
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ struct function_table vtable;
+ int addrlen;
+
+ addr = parse_scheme(peer, &port, &vtable);
+ if (!addr) {
+ ErrPrint("Failed to parse scheme\n");
+ return -EINVAL;
+ }
+
+ switch (vtable.type) {
case SCHEME_LOCAL:
- sockaddr = (struct sockaddr *)&un_addr;
- addrlen = sizeof(un_addr);
- break;
+ sockaddr = (struct sockaddr *)&un_addr;
+ addrlen = sizeof(un_addr);
+ break;
case SCHEME_REMOTE:
- sockaddr = (struct sockaddr *)&in_addr;
- addrlen = sizeof(in_addr);
- break;
+ sockaddr = (struct sockaddr *)&in_addr;
+ addrlen = sizeof(in_addr);
+ break;
default:
- free(addr);
- return -EINVAL;
- }
-
- handle = vtable.create_socket(addr, port, sockaddr);
- free(addr);
- if (handle < 0) {
- return handle;
- }
-
- ret = connect(handle, sockaddr, addrlen);
- if (ret < 0) {
- ret = -errno;
- ErrPrint("Failed to connect to server [%s] %s\n",
- peer, strerror(errno));
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
+ free(addr);
+ return -EINVAL;
}
- return ret;
- }
-
- ret = vtable.setup_handle(handle);
- if (ret < 0) {
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
+ handle = vtable.create_socket(addr, port, sockaddr);
+ free(addr);
+ if (handle < 0) {
+ return handle;
}
- return ret;
- }
-
- return handle;
-}
-EAPI int secure_socket_create_server(const char *peer)
-{
- int port;
- char *addr;
- int handle;
- int ret;
- struct sockaddr *sockaddr;
- struct sockaddr_in in_addr;
- struct sockaddr_un un_addr;
- struct function_table vtable;
- int addrlen;
-
- addr = parse_scheme(peer, &port, &vtable);
- if (!addr) {
- ErrPrint("Failed to parse scheme\n");
- return -EINVAL;
- }
-
- switch (vtable.type) {
- case SCHEME_LOCAL:
- sockaddr = (struct sockaddr *)&un_addr;
- addrlen = sizeof(un_addr);
- break;
- case SCHEME_REMOTE:
- sockaddr = (struct sockaddr *)&in_addr;
- addrlen = sizeof(in_addr);
- break;
- default:
- free(addr);
- return -EINVAL;
- }
+ if (label) {
+ if (fsetxattr(handle, "security.SMACK64IPIN", label, strlen(label), 0) < 0) {
+ ErrPrint("Failed to set SMACK label[%s] [%s]\n", label, strerror(errno));
+ }
- handle = vtable.create_socket(addr, port, sockaddr);
- free(addr);
- if (handle < 0) {
- return handle;
- }
+ if (fsetxattr(handle, "security.SMACK64IPOUT", label, strlen(label), 0) < 0) {
+ ErrPrint("Failed to set SMACK label[%s] [%s]\n", label, strerror(errno));
+ }
+ }
- ret = bind(handle, sockaddr, addrlen);
- if (ret < 0) {
- ret = -errno;
- ErrPrint("bind: %s\n", strerror(errno));
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
+ ret = bind(handle, sockaddr, addrlen);
+ if (ret < 0) {
+ ret = -errno;
+ ErrPrint("bind: %s\n", strerror(errno));
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+ return ret;
}
- return ret;
- }
- ret = listen(handle, BACKLOG);
- if (ret < 0) {
- ret = -errno;
- ErrPrint("listen: %s\n", strerror(errno));
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
+ ret = listen(handle, BACKLOG);
+ if (ret < 0) {
+ ret = -errno;
+ ErrPrint("listen: %s\n", strerror(errno));
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+ return ret;
}
- return ret;
- }
- if (vtable.type == SCHEME_LOCAL) {
- if (chmod(peer, 0666) < 0) {
- ErrPrint("Failed to change the permission of a socket (%s)\n", strerror(errno));
+ if (vtable.type == SCHEME_LOCAL) {
+ if (chmod(peer, 0666) < 0) {
+ ErrPrint("Failed to change the permission of a socket (%s)\n", strerror(errno));
+ }
}
- }
- return handle;
+ return handle;
}
EAPI int secure_socket_get_connection_handle(int server_handle)
{
- struct sockaddr_in in_addr;
- struct sockaddr_un un_addr;
- struct sockaddr *addr;
- int handle;
- int ret;
- socklen_t size = sizeof(un_addr);
-
- /* Finding the largest buffer */
- if (sizeof(in_addr) > sizeof(un_addr)) {
- addr = (struct sockaddr *)&in_addr;
- size = sizeof(in_addr);
- } else {
- addr = (struct sockaddr *)&un_addr;
- size = sizeof(un_addr);
- }
-
- handle = accept(server_handle, addr, &size);
- if (handle < 0) {
- ret = -errno;
- ErrPrint("Failed to accept a new client %s\n", strerror(errno));
- return ret;
- }
-
- if (addr->sa_family == AF_UNIX) {
- ret = setup_unix_handle(handle);
- if (ret < 0) {
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
- }
+ struct sockaddr_in in_addr;
+ struct sockaddr_un un_addr;
+ struct sockaddr *addr;
+ int handle;
+ int ret;
+ socklen_t size = sizeof(un_addr);
+
+ /* Finding the largest buffer */
+ if (sizeof(in_addr) > sizeof(un_addr)) {
+ addr = (struct sockaddr *)&in_addr;
+ size = sizeof(in_addr);
+ } else {
+ addr = (struct sockaddr *)&un_addr;
+ size = sizeof(un_addr);
+ }
- handle = ret;
+ handle = accept(server_handle, addr, &size);
+ if (handle < 0) {
+ ret = -errno;
+ ErrPrint("Failed to accept a new client %s\n", strerror(errno));
+ return ret;
}
- } else if (addr->sa_family == AF_INET) {
- ret = setup_inet_handle(handle);
- if (ret < 0) {
- if (close(handle) < 0) {
- ErrPrint("close: %s\n", strerror(errno));
- }
- handle = ret;
+ if (addr->sa_family == AF_UNIX) {
+ ret = setup_unix_handle(handle);
+ if (ret < 0) {
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+
+ handle = ret;
+ }
+ } else if (addr->sa_family == AF_INET) {
+ ret = setup_inet_handle(handle);
+ if (ret < 0) {
+ if (close(handle) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+
+ handle = ret;
+ }
+ } else {
+ ErrPrint("Unknown address family: %d\n", addr->sa_family);
}
- } else {
- ErrPrint("Unknown address family: %d\n", addr->sa_family);
- }
- return handle;
+ return handle;
}
EAPI int secure_socket_send_with_fd(int handle, const char *buffer, int size, int fd)
{
- struct msghdr msg;
- struct iovec iov;
- union {
- struct cmsghdr hdr;
- char control[CMSG_SPACE(sizeof(int))];
- } cmsgu;
- int ret;
-
- if (!buffer || size <= 0) {
- ErrPrint("Reject: 0 byte data sending\n");
- return -EINVAL;
- }
-
- memset(&msg, 0, sizeof(msg));
- iov.iov_base = (char *)buffer;
- iov.iov_len = size;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- if (fd >= 0) {
- struct cmsghdr *cmsg;
- int *cdata;
+ struct msghdr msg;
+ struct iovec iov;
+ union {
+ struct cmsghdr hdr;
+ char control[CMSG_SPACE(sizeof(int))];
+ } cmsgu;
+ int ret;
- msg.msg_control = cmsgu.control;
- msg.msg_controllen = sizeof(cmsgu.control);
+ if (!buffer || size <= 0) {
+ ErrPrint("Reject: 0 byte data sending\n");
+ return -EINVAL;
+ }
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cdata = (int *)CMSG_DATA(cmsg);
- *cdata = fd;
- }
-
- ret = sendmsg(handle, &msg, 0);
- if (ret < 0) {
- ret = -errno;
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
- return -EAGAIN;
+ memset(&msg, 0, sizeof(msg));
+ iov.iov_base = (char *)buffer;
+ iov.iov_len = size;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (fd >= 0) {
+ struct cmsghdr *cmsg;
+ int *cdata;
+
+ msg.msg_control = cmsgu.control;
+ msg.msg_controllen = sizeof(cmsgu.control);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cdata = (int *)CMSG_DATA(cmsg);
+ *cdata = fd;
+ }
+
+ ret = sendmsg(handle, &msg, 0);
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
+ return -EAGAIN;
+ }
+ ErrPrint("Failed to send message [%s]\n", strerror(errno));
+ return ret;
}
- ErrPrint("Failed to send message [%s]\n", strerror(errno));
- return ret;
- }
- return iov.iov_len;
+ return iov.iov_len;
}
EAPI int secure_socket_send(int handle, const char *buffer, int size)
{
- return secure_socket_send_with_fd(handle, buffer, size, -1);
+ return secure_socket_send_with_fd(handle, buffer, size, -1);
}
EAPI int secure_socket_recv_with_fd(int handle, char *buffer, int size, int *sender_pid, int *fd)
{
- struct msghdr msg;
- struct cmsghdr *cmsg;
- struct iovec iov;
- char control[1024];
- int _pid;
- int ret;
-
- if (size <= 0 || !buffer) {
- return -EINVAL;
- }
-
- if (!sender_pid) {
- sender_pid = &_pid;
- }
-
- memset(&msg, 0, sizeof(msg));
- iov.iov_base = buffer;
- iov.iov_len = size;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = control;
- msg.msg_controllen = sizeof(control);
-
- ret = recvmsg(handle, &msg, 0);
- if (ret == 0) {
- /*!< Disconnected */
- DbgPrint("Disconnected\n");
- return 0;
- }
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ char control[1024];
+ int _pid;
+ int ret;
- if (ret < 0) {
- ret = -errno;
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
- return -EAGAIN;
+ if (size <= 0 || !buffer) {
+ return -EINVAL;
}
- ErrPrint("Failed to recvmsg [%s]\n", strerror(errno));
- return ret;
- }
-
- *sender_pid = -1; /* In case of remote socket, cannot delivery this */
- cmsg = CMSG_FIRSTHDR(&msg);
- while (cmsg) {
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
- struct ucred *cred;
-
- cred = (struct ucred *)CMSG_DATA(cmsg);
- *sender_pid = cred->pid;
- } else if (fd && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
- int *cdata;
- cdata = (int *)CMSG_DATA(cmsg);
- *fd = *cdata;
+ if (!sender_pid) {
+ sender_pid = &_pid;
}
- cmsg = CMSG_NXTHDR(&msg, cmsg);
- }
+ memset(&msg, 0, sizeof(msg));
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+
+ ret = recvmsg(handle, &msg, 0);
+ if (ret == 0) {
+ /*!< Disconnected */
+ DbgPrint("Disconnected\n");
+ return 0;
+ }
- return iov.iov_len;
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ ErrPrint("handle[%d] size[%d] Try again [%s]\n", handle, size, strerror(errno));
+ return -EAGAIN;
+ }
+
+ ErrPrint("Failed to recvmsg [%s]\n", strerror(errno));
+ return ret;
+ }
+
+ *sender_pid = -1; /* In case of remote socket, cannot delivery this */
+ cmsg = CMSG_FIRSTHDR(&msg);
+ while (cmsg) {
+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
+ struct ucred *cred;
+
+ cred = (struct ucred *)CMSG_DATA(cmsg);
+ *sender_pid = cred->pid;
+ } else if (fd && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+ int *cdata;
+ cdata = (int *)CMSG_DATA(cmsg);
+ *fd = *cdata;
+ }
+
+ cmsg = CMSG_NXTHDR(&msg, cmsg);
+ }
+
+ return iov.iov_len;
}
EAPI int secure_socket_recv(int handle, char *buffer, int size, int *sender_pid)
{
- return secure_socket_recv_with_fd(handle, buffer, size, sender_pid, NULL);
+ return secure_socket_recv_with_fd(handle, buffer, size, sender_pid, NULL);
}
EAPI int secure_socket_destroy_handle(int handle)
{
- if (close(handle) < 0) {
- int ret;
- ret = -errno;
- ErrPrint("close: %s\n", strerror(errno));
- return ret;
- }
+ if (close(handle) < 0) {
+ int ret;
+ ret = -errno;
+ ErrPrint("close: %s\n", strerror(errno));
+ return ret;
+ }
- return 0;
+ return 0;
}
#undef _GNU_SOURCE