Update copyright dates
[src/app-framework-binder.git] / src / afb-api-ws.c
index 6d8506c..4ea8610 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2018 "IoT.bzh"
+ * Copyright (C) 2015-2020 "IoT.bzh"
  * Author José Bollo <jose.bollo@iot.bzh>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,13 +43,19 @@ struct api_ws_server
        struct afb_apiset *apiset;      /* the apiset for calling */
        struct fdev *fdev;              /* fdev handler */
        uint16_t offapi;                /* api name of the interface */
-       char uri[1];                    /* the uri of the server socket */
+       char uri[];                     /* the uri of the server socket */
 };
 
 /******************************************************************************/
 /***       C L I E N T                                                      ***/
 /******************************************************************************/
 
+static struct fdev *reopen_client(void *closure)
+{
+       const char *uri = closure;
+       return afb_socket_open_fdev(uri, 0);
+}
+
 int afb_api_ws_add_client(const char *uri, struct afb_apiset *declare_set, struct afb_apiset *call_set, int strong)
 {
        struct afb_stub_ws *stubws;
@@ -73,8 +79,16 @@ int afb_api_ws_add_client(const char *uri, struct afb_apiset *declare_set, struc
                        ERROR("can't setup client ws service to %s", uri);
                        fdev_unref(fdev);
                } else {
-                       if (afb_stub_ws_client_add(stubws, declare_set) >= 0)
+                       if (afb_stub_ws_client_add(stubws, declare_set) >= 0) {
+#if 1
+                               /* it is asserted here that uri is never released */
+                               afb_stub_ws_client_robustify(stubws, reopen_client, (void*)uri, NULL);
+#else
+                               /* it is asserted here that uri is released, so use a copy */
+                               afb_stub_ws_client_robustify(stubws, reopen_client, strdup(uri), free);
+#endif
                                return 0;
+                       }
                        ERROR("can't add the client to the apiset for service %s", uri);
                        afb_stub_ws_unref(stubws);
                }
@@ -116,7 +130,9 @@ static void api_ws_server_accept(struct api_ws_server *apiws)
                        close(fd);
                } else {
                        server = afb_stub_ws_create_server(fdev, &apiws->uri[apiws->offapi], apiws->apiset);
-                       if (!server)
+                       if (server)
+                               afb_stub_ws_set_on_hangup(server, afb_stub_ws_unref);
+                       else
                                ERROR("can't serve accepted connection to %s: %m", apiws->uri);
                }
        }
@@ -128,10 +144,10 @@ static void api_ws_server_listen_callback(void *closure, uint32_t revents, struc
 {
        struct api_ws_server *apiws = closure;
 
-       if ((revents & EPOLLIN) != 0)
-               api_ws_server_accept(apiws);
        if ((revents & EPOLLHUP) != 0)
                api_ws_server_connect(apiws);
+       else if ((revents & EPOLLIN) != 0)
+               api_ws_server_accept(apiws);
 }
 
 static void api_ws_server_disconnect(struct api_ws_server *apiws)
@@ -192,7 +208,7 @@ int afb_api_ws_add_server(const char *uri, struct afb_apiset *declare_set, struc
        /* make the structure */
        lapi = strlen(api);
        extra = luri == (api - uri) + lapi ? 0 : lapi + 1;
-       apiws = malloc(sizeof * apiws + luri + extra);
+       apiws = malloc(sizeof * apiws + 1 + luri + extra);
        if (!apiws) {
                ERROR("out of memory");
                errno = ENOMEM;