/*
- * Copyright (C) 2016, 2017, 2018 "IoT.bzh"
+ * Copyright (C) 2016-2019 "IoT.bzh"
* Author José Bollo <jose.bollo@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
#include "afb-api-v3.h"
#include "afb-apiset.h"
#include "afb-fdev.h"
+#include "afb-socket.h"
#include "fdev.h"
#include "verbose.h"
/*************************************************************************************/
-/**
- * Creates the supervisor socket for 'path' and return it
- * return -1 in case of failure
- */
-static int create_supervision_socket(const char *path)
-{
- int fd, rc;
- struct sockaddr_un addr;
- size_t length;
-
- /* check the path's length */
- length = strlen(path);
- if (length >= 108) {
- ERROR("Path name of supervision socket too long: %d", (int)length);
- errno = ENAMETOOLONG;
- return -1;
- }
-
- /* create a socket */
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- ERROR("Can't create socket: %m");
- return fd;
- }
-
- /* setup the bind to a path */
- memset(&addr, 0, sizeof addr);
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, path);
- if (addr.sun_path[0] == '@')
- addr.sun_path[0] = 0; /* abstract sockets */
- else
- unlink(path);
-
- /* binds the socket to the path */
- rc = bind(fd, (struct sockaddr *) &addr, (socklen_t)(sizeof addr));
- if (rc < 0) {
- ERROR("can't bind socket to %s", path);
- close(fd);
- return rc;
- }
- return fd;
-}
-
/**
* send on 'fd' an initiator with 'command'
* return 0 on success or -1 on failure
static void on_supervised_hangup(struct afb_stub_ws *stub)
{
struct supervised *s, **ps;
+
+ /* Search the supervised of the ws-stub */
pthread_mutex_lock(&mutex);
ps = &superviseds;
while ((s = *ps) && s->stub != stub)
ps = &s->next;
+
+ /* unlink the supervised if found */
if (s)
*ps = s->next;
pthread_mutex_unlock(&mutex);
+
+ /* forgive the ws-stub */
afb_stub_ws_unref(stub);
+
+ /* forgive the supervised */
if (s) {
afb_event_push(event_del_pid, json_object_new_int((int)s->cred->pid));
afb_cred_unref(s->cred);
s->next = superviseds;
superviseds = s;
pthread_mutex_unlock(&mutex);
- afb_stub_ws_on_hangup(s->stub, on_supervised_hangup);
+ afb_stub_ws_set_on_hangup(s->stub, on_supervised_hangup);
return 0;
}
{
if ((revents & EPOLLIN) != 0)
accept_supervision_link((int)(intptr_t)closure);
- if ((revents & EPOLLHUP) != 0) {
+ else if ((revents & EPOLLHUP) != 0) {
ERROR("supervision socket closed");
exit(1);
}
xreq = xreq_from_req_x2(req);
args = afb_xreq_json(xreq);
+
+ /* extract the pid */
if (!json_object_object_get_ex(args, "pid", &item)) {
afb_xreq_reply(xreq, NULL, "no-pid", NULL);
return;
afb_xreq_reply(xreq, NULL, "bad-pid", NULL);
return;
}
+
+ /* get supervised of pid */
s = supervised_of_pid((pid_t)p);
if (!s) {
afb_req_reply(req, NULL, "unknown-pid", NULL);
return;
}
json_object_object_del(args, "pid");
+
+ /* replace the verb to call if needed */
if (verb)
xreq->request.called_verb = verb;
+
+ /* call it now */
api = afb_stub_ws_client_api(s->stub);
api.itf->call(api.closure, xreq);
}
*/
static int init_supervisor(afb_api_t api)
{
- int rc, fd;
-
event_add_pid = afb_api_make_event(api, "add-pid");
if (!afb_event_is_valid(event_add_pid)) {
ERROR("Can't create added event");
}
/* create the supervision socket */
- fd = create_supervision_socket(supervision_socket_path);
- if (fd < 0)
- return fd;
-
- /* listen the socket */
- rc = listen(fd, 5);
- if (rc < 0) {
- ERROR("refused to listen on socket");
- return rc;
- }
+ supervision_fdev = afb_socket_open_fdev(supervision_socket_path, 1);
+ if (!supervision_fdev)
+ return -1;
- /* integrate the socket to the loop */
- supervision_fdev = afb_fdev_create(fd);
- if (rc < 0) {
- ERROR("handling socket event isn't possible");
- return rc;
- }
fdev_set_events(supervision_fdev, EPOLLIN);
- fdev_set_callback(supervision_fdev, listening, (void*)(intptr_t)fd);
+ fdev_set_callback(supervision_fdev, listening,
+ (void*)(intptr_t)fdev_fd(supervision_fdev));
return 0;
}