aboutsummaryrefslogtreecommitdiffstats
path: root/src/afb-api-ws.c
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2018-02-22 13:22:48 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2018-02-22 13:22:48 +0100
commitca820c65c2b03a24e8936218171c6c1d138fd1f7 (patch)
treef7e31ea8e63d3321af64226e360a78c504a09bb3 /src/afb-api-ws.c
parentf15ea770dd9b13a20331853a026091316984f9ca (diff)
fdev: Introduce fdev for file event handling
This is an effort to keep cutting dependency to systemd. Change-Id: I9a0c032a1095e297c7f3ac5b67827fda3658b8d9 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'src/afb-api-ws.c')
-rw-r--r--src/afb-api-ws.c97
1 files changed, 52 insertions, 45 deletions
diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c
index 7fbe5be1..489b43b1 100644
--- a/src/afb-api-ws.c
+++ b/src/afb-api-ws.c
@@ -30,19 +30,19 @@
#include <sys/socket.h>
#include <sys/un.h>
-#include <systemd/sd-event.h>
+#include "afb-fdev.h"
+#include "afb-systemd.h"
#include "afb-api.h"
#include "afb-apiset.h"
-#include "afb-systemd.h"
#include "afb-stub-ws.h"
#include "verbose.h"
+#include "fdev.h"
struct api_ws
{
char *path; /* path of the object for the API */
char *api; /* api name of the interface */
- int fd; /* file descriptor */
- sd_event_source *listensrc; /**< systemd source for server socket */
+ struct fdev *fdev; /* fdev handler */
struct afb_apiset *apiset;
};
@@ -77,7 +77,6 @@ static struct api_ws *api_ws_make(const char *path)
goto error2;
}
- api->fd = -1;
return api;
error2:
@@ -176,7 +175,7 @@ static int api_ws_socket(const char *path, int server)
/* check for systemd socket */
if (0 == strncmp(path, "sd:", 3))
- fd = systemd_fds_for(path + 3);
+ fd = afb_systemd_fds_for(path + 3);
else {
/* check for unix socket */
if (0 == strncmp(path, "unix:", 5))
@@ -200,6 +199,24 @@ static int api_ws_socket(const char *path, int server)
return fd;
}
+static struct fdev *api_ws_socket_fdev(const char *path, int server)
+{
+ int fd;
+ struct fdev *fdev;
+
+ fd = api_ws_socket(path, server);
+ if (fd < 0)
+ fdev = 0;
+ else {
+ fdev = afb_fdev_create(fd);
+ if (!fdev)
+ close(fd);
+ }
+ if (!fdev)
+ ERROR("can't make %s socket for %s", server ? "server" : "client", path);
+ return fdev;
+}
+
/**********************************************************************************/
int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int strong)
@@ -213,27 +230,23 @@ int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int stron
goto error;
/* connect to the service */
- apiws->fd = api_ws_socket(apiws->path, 0);
- if (apiws->fd < 0) {
- ERROR("can't connect to ws service %s", apiws->path);
+ apiws->fdev = api_ws_socket_fdev(apiws->path, 0);
+ if (!apiws->fdev)
goto error2;
- }
- stubws = afb_stub_ws_create_client(apiws->fd, apiws->api, apiset);
+ stubws = afb_stub_ws_create_client(apiws->fdev, apiws->api, apiset);
if (!stubws) {
ERROR("can't setup client ws service to %s", apiws->path);
goto error3;
}
if (afb_stub_ws_client_add(stubws, apiset) < 0) {
ERROR("can't add the client to the apiset for service %s", apiws->path);
- goto error4;
+ goto error3;
}
free(apiws);
return 0;
-error4:
- afb_stub_ws_unref(stubws);
error3:
- close(apiws->fd);
+ afb_stub_ws_unref(stubws);
error2:
free(apiws);
error:
@@ -250,9 +263,9 @@ int afb_api_ws_add_client_weak(const char *path, struct afb_apiset *apiset)
return afb_api_ws_add_client(path, apiset, 0);
}
-static int api_ws_server_accept_client(struct api_ws *apiws, int fd)
+static int api_ws_server_accept_client(struct api_ws *apiws, struct fdev *fdev)
{
- return -!afb_stub_ws_create_server(fd, apiws->api, apiws->apiset);
+ return -!afb_stub_ws_create_server(fdev, apiws->api, apiws->apiset);
}
static void api_ws_server_accept(struct api_ws *apiws)
@@ -260,20 +273,28 @@ static void api_ws_server_accept(struct api_ws *apiws)
int rc, fd;
struct sockaddr addr;
socklen_t lenaddr;
+ struct fdev *fdev;
lenaddr = (socklen_t)sizeof addr;
- fd = accept(apiws->fd, &addr, &lenaddr);
- if (fd >= 0) {
- rc = api_ws_server_accept_client(apiws, fd);
- if (rc >= 0)
- return;
- close(fd);
+ fd = accept(fdev_fd(apiws->fdev), &addr, &lenaddr);
+ if (fd < 0) {
+ ERROR("can't accept connection to %s: %m", apiws->path);
+ } else {
+ fdev = afb_fdev_create(fd);
+ if (!fdev) {
+ ERROR("can't hold accepted connection to %s: %m", apiws->path);
+ close(fd);
+ } else {
+ rc = api_ws_server_accept_client(apiws, fdev);
+ if (rc < 0)
+ ERROR("can't serve accepted connection to %s: %m", apiws->path);
+ }
}
}
static int api_ws_server_connect(struct api_ws *apiws);
-static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t revents, void *closure)
+static void api_ws_server_listen_callback(void *closure, uint32_t revents, struct fdev *fdev)
{
struct api_ws *apiws = closure;
@@ -281,42 +302,28 @@ static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t
api_ws_server_accept(apiws);
if ((revents & EPOLLHUP) != 0)
api_ws_server_connect(apiws);
- return 0;
}
static void api_ws_server_disconnect(struct api_ws *apiws)
{
- if (apiws->listensrc != NULL) {
- sd_event_source_unref(apiws->listensrc);
- apiws->listensrc = NULL;
- }
- if (apiws->fd >= 0) {
- close(apiws->fd);
- apiws->fd = -1;
- }
+ fdev_unref(apiws->fdev);
+ apiws->fdev = 0;
}
static int api_ws_server_connect(struct api_ws *apiws)
{
- int rc;
-
/* ensure disconnected */
api_ws_server_disconnect(apiws);
/* request the service object name */
- apiws->fd = api_ws_socket(apiws->path, 1);
- if (apiws->fd < 0)
+ apiws->fdev = api_ws_socket_fdev(apiws->path, 1);
+ if (!apiws->fdev)
ERROR("can't create socket %s", apiws->path);
else {
/* listen for service */
- rc = sd_event_add_io(afb_systemd_get_event_loop(),
- &apiws->listensrc, apiws->fd, EPOLLIN,
- api_ws_server_listen_callback, apiws);
- if (rc >= 0)
- return 0;
- close(apiws->fd);
- errno = -rc;
- ERROR("can't add ws object %s", apiws->path);
+ fdev_set_events(apiws->fdev, EPOLLIN);
+ fdev_set_callback(apiws->fdev, api_ws_server_listen_callback, apiws);
+ return 0;
}
return -1;
}