barbieri pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=a8d1aa14413aa95349636172b5aaad3510e68b54

commit a8d1aa14413aa95349636172b5aaad3510e68b54
Author: Gustavo Sverzut Barbieri <[email protected]>
Date:   Fri Nov 25 19:39:01 2016 -0200

    efl_debug (client and server): now on top of efl_net_{server,dialer}_simple.
    
    Much simpler! :-D
---
 src/bin/efl/efl_debug.c        |  81 ++------
 src/bin/efl/efl_debug_common.c |  70 +++++++
 src/bin/efl/efl_debug_common.h |  28 ++-
 src/bin/efl/efl_debugd.c       | 448 ++++++++++++++++++++++++++++++-----------
 4 files changed, 429 insertions(+), 198 deletions(-)

diff --git a/src/bin/efl/efl_debug.c b/src/bin/efl/efl_debug.c
index 5c0ee95..177dfa9 100644
--- a/src/bin/efl/efl_debug.c
+++ b/src/bin/efl/efl_debug.c
@@ -16,8 +16,6 @@
  * if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define EFL_BETA_API_SUPPORT 1
-#define EFL_EO_API_SUPPORT 1
 #include "efl_debug_common.h"
 
 static Eo *dialer;
@@ -26,19 +24,15 @@ static Eina_List *waiting;
 
 static int retval = EXIT_SUCCESS;
 
-static const char CLST[4] = "CLST";
-
 static void
-_process_reply(const char op[static 4], const Eina_Slice payload)
+_process_reply(void *data EINA_UNUSED, const char op[static 4], const 
Eina_Slice payload)
 {
-#define IS_OP(x) memcmp(op, x, 4) == 0
-
    if (IS_OP(CLST))
      {
         int mypid = getpid();
         size_t offset;
 
-        waiting = eina_list_remove(waiting, CLST);
+        waiting = eina_list_remove(waiting, OP_CLST);
 
         for (offset = 0; offset + sizeof(int) <= payload.len; offset += 
sizeof(int))
           {
@@ -57,76 +51,23 @@ _process_reply(const char op[static 4], const Eina_Slice 
payload)
      }
 
    if (!waiting) ecore_main_loop_quit();
-
-#undef IS_OP
 }
 
 static void
 _on_data(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
 {
-   Eina_Slice slice, payload;
-   Efl_Debug_Message_Header msgheader;
-
-   if (!efl_io_buffered_stream_slice_get(dialer, &slice))
-     return;
-
-   if (slice.len < sizeof(msgheader))
-     return;
-
-   memcpy(&msgheader, slice.mem, sizeof(msgheader));
-   if (msgheader.size < 4) /* must contain at last 4 byte opcode */
+   if (!received_data(dialer, _process_reply, NULL))
      {
-        fprintf(stderr, "ERROR: invalid message header, size=%u\n", 
msgheader.size);
         retval = EXIT_FAILURE;
         ecore_main_loop_quit();
-        return;
      }
-
-   if (msgheader.size + 4 > slice.len)
-     return;
-
-   payload.bytes = slice.bytes + sizeof(msgheader);
-   payload.len = msgheader.size - 4;
-
-   _process_reply(msgheader.op, payload);
-
-   efl_io_buffered_stream_discard(dialer, sizeof(msgheader) + payload.len);
 }
 
 static Eina_Bool
 _command_send(const char op[static 4], const void *data, unsigned int len)
 {
-   Eina_Error err;
-   Efl_Debug_Message_Header msghdr = {
-     .size = 4 + len,
-   };
-   Eina_Slice s, r;
-
-   memcpy(msghdr.op, op, 4);
-
-   s.mem = &msghdr;
-   s.len = sizeof(msghdr);
-
-   err = efl_io_writer_write(dialer, &s, &r);
-   if (err || r.len) goto end;
-
-   if (!len) goto end;
-
-   s.mem = data;
-   s.len = len;
-   err = efl_io_writer_write(dialer, &s, &r);
-
- end:
-   if (err)
+   if (!send_data(dialer, op, data, len))
      {
-        fprintf(stderr, "ERROR: could not queue message '%.4s': %s\n", op, 
eina_error_msg_get(err));
-        retval = EXIT_FAILURE;
-        return EINA_FALSE;
-     }
-
-   if (r.len)
-     {
-        fprintf(stderr, "ERROR: could not queue message '%.4s': out of 
memory\n", op);
         retval = EXIT_FAILURE;
         return EINA_FALSE;
      }
@@ -134,6 +75,8 @@ _command_send(const char op[static 4], const void *data, 
unsigned int len)
    return EINA_TRUE;
 }
 
+#define command_send(op, data, len) _command_send(OP_ ## op, data, len)
+
 static void
 _write_finished(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
 {
@@ -234,9 +177,9 @@ main(int argc, char **argv)
 
         if (strcmp(cmd, "list") == 0)
           {
-             if (!_command_send("LIST", NULL, 0))
+             if (!command_send(LIST, NULL, 0))
                goto end;
-             waiting = eina_list_append(waiting, CLST);
+             waiting = eina_list_append(waiting, OP_CLST);
           }
         else if (strcmp(cmd, "pon") == 0)
           {
@@ -249,7 +192,7 @@ main(int argc, char **argv)
              else
                {
                   int data[2] = {atoi(argv[i + 1]), atoi(argv[1 + 2])};
-                  if (!_command_send("PLON", data, sizeof(data)))
+                  if (!command_send(PLON, data, sizeof(data)))
                     goto end;
                   i += 2;
                }
@@ -265,7 +208,7 @@ main(int argc, char **argv)
              else
                {
                   int data[1] = {atoi(argv[i + 1])};
-                  if (!_command_send("PLOFF", data, sizeof(data)))
+                  if (!command_send(PLOF, data, sizeof(data)))
                     goto end;
                   i++;
                }
@@ -281,7 +224,7 @@ main(int argc, char **argv)
              else
                {
                   int data[1] = {atoi(argv[i + 1])};
-                  if (!_command_send("EVON", data, sizeof(data)))
+                  if (!command_send(EVON, data, sizeof(data)))
                     goto end;
                   i++;
                }
@@ -297,7 +240,7 @@ main(int argc, char **argv)
              else
                {
                   int data[1] = {atoi(argv[i + 1])};
-                  if (!_command_send("EVOF", data, sizeof(data)))
+                  if (!command_send(EVOF, data, sizeof(data)))
                     goto end;
                   i++;
                }
diff --git a/src/bin/efl/efl_debug_common.c b/src/bin/efl/efl_debug_common.c
index 1ef2967..7776d78 100644
--- a/src/bin/efl/efl_debug_common.c
+++ b/src/bin/efl/efl_debug_common.c
@@ -111,3 +111,73 @@ _proto_read(unsigned char **buf, unsigned int *buf_size,
    *buf_size = new_buf_size;
    return (int)size;
 }
+
+Eina_Bool
+received_data(Eo *sock, void (*handle)(void *data, const char op[static 4], 
const Eina_Slice payload), const void *data)
+{
+   Eina_Slice slice, payload;
+   Efl_Debug_Message_Header msgheader;
+
+   if (!efl_io_buffered_stream_slice_get(sock, &slice))
+     return EINA_TRUE;
+
+   if (slice.len < sizeof(msgheader))
+     return EINA_TRUE;
+
+   memcpy(&msgheader, slice.mem, sizeof(msgheader));
+   if (msgheader.size < 4) /* must contain at last 4 byte opcode */
+     {
+        fprintf(stderr, "ERROR: invalid message header, size=%u\n", 
msgheader.size);
+        return EINA_FALSE;
+     }
+
+   if (msgheader.size + 4 > slice.len)
+     return EINA_TRUE;
+
+   payload.bytes = slice.bytes + sizeof(msgheader);
+   payload.len = msgheader.size - 4;
+
+   handle((void *)data, msgheader.op, payload);
+
+   efl_io_buffered_stream_discard(sock, sizeof(msgheader) + payload.len);
+   return EINA_TRUE;
+}
+
+Eina_Bool
+send_data(Eo *sock, const char op[static 4], const void *data, unsigned int 
len)
+{
+   Eina_Error err;
+   Efl_Debug_Message_Header msghdr = {
+     .size = 4 + len,
+   };
+   Eina_Slice s, r;
+
+   memcpy(msghdr.op, op, 4);
+
+   s.mem = &msghdr;
+   s.len = sizeof(msghdr);
+
+   err = efl_io_writer_write(sock, &s, &r);
+   if (err || r.len) goto end;
+
+   if (!len) goto end;
+
+   s.mem = data;
+   s.len = len;
+   err = efl_io_writer_write(sock, &s, &r);
+
+ end:
+   if (err)
+     {
+        fprintf(stderr, "ERROR: could not queue message '%.4s': %s\n", op, 
eina_error_msg_get(err));
+        return EINA_FALSE;
+     }
+
+   if (r.len)
+     {
+        fprintf(stderr, "ERROR: could not queue message '%.4s': out of 
memory\n", op);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
diff --git a/src/bin/efl/efl_debug_common.h b/src/bin/efl/efl_debug_common.h
index 29e9739..fdb9e45 100644
--- a/src/bin/efl/efl_debug_common.h
+++ b/src/bin/efl/efl_debug_common.h
@@ -19,6 +19,9 @@
 #ifndef EFL_DEBUG_COMMON_H
 #define EFL_DEBUG_COMMON_H 1
 
+#define EFL_BETA_API_SUPPORT 1
+#define EFL_EO_API_SUPPORT 1
+
 #include <Eina.h>
 #include <Ecore.h>
 #include <Ecore_Con.h>
@@ -41,15 +44,20 @@ int _proto_read(unsigned char **buf, unsigned int *buf_size,
    memcpy(&dst, ((unsigned char *)buf) + off, sizeof(dst))
 #define store_val(buf, off, src) \
    memcpy(buf + off, &src, sizeof(src))
-#define send_cli(cli, op, data, size) \
-   do { \
-      unsigned char head[8]; \
-      char *op2 = op; \
-      int size2 = size + 4; \
-      memcpy(head + 0, &size2, 4); \
-      memcpy(head + 4, op2, 4); \
-      ecore_con_client_send(cli, head, 8); \
-      if (size > 0) ecore_con_client_send(cli, data, size); \
-   } while (0)
+
+#define IS_OP(x) memcmp(op, OP_ ## x, 4) == 0
+
+#define DECLARE_OP(x) static char OP_ ## x[4] = #x
+DECLARE_OP(LIST);
+DECLARE_OP(CLST);
+DECLARE_OP(PLON);
+DECLARE_OP(PLOF);
+DECLARE_OP(EVON);
+DECLARE_OP(EVOF);
+DECLARE_OP(EVLG);
+DECLARE_OP(HELO);
+
+Eina_Bool send_data(Eo *sock, const char op[static 4], const void *data, 
unsigned int len);
+Eina_Bool received_data(Eo *sock, void (*handle)(void *data, const char 
op[static 4], const Eina_Slice payload), const void *data);
 
 #endif
diff --git a/src/bin/efl/efl_debugd.c b/src/bin/efl/efl_debugd.c
index a07fe3f..1934c81 100644
--- a/src/bin/efl/efl_debugd.c
+++ b/src/bin/efl/efl_debugd.c
@@ -22,7 +22,8 @@ typedef struct _Client Client;
 
 struct _Client
 {
-   Ecore_Con_Client *client;
+   Eo *client;
+
    unsigned char    *buf;
    unsigned int      buf_size;
 
@@ -34,9 +35,51 @@ struct _Client
    pid_t             pid;
 };
 
-static Ecore_Con_Server *svr = NULL;
+static Eo *server;
+
 static Eina_List *clients = NULL;
 
+static int retval;
+
+static int _log_dom = -1;
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
+
+#ifdef CRI
+# undef CRI
+#endif
+#define CRI(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
+
+
+#define send_cli(cl, op, data, len)                             \
+  do                                                            \
+    {                                                           \
+       if (!send_data(cl->client, OP_ ## op, data, len))        \
+         {                                                      \
+            if (!efl_io_closer_closed_get(cl->client))          \
+              efl_io_closer_close(cl->client);                  \
+         }                                                      \
+    }                                                           \
+  while (0)
+
 static Client *
 _client_pid_find(int pid)
 {
@@ -48,6 +91,8 @@ _client_pid_find(int pid)
      {
         if (c->pid == pid) return c;
      }
+
+   WRN("no client pid=%d", pid);
    return NULL;
 }
 
@@ -55,27 +100,35 @@ static Eina_Bool
 _cb_evlog(void *data)
 {
    Client *c = data;
-   send_cli(c->client, "EVLG", NULL, 0);
+   send_cli(c, EVLG, NULL, 0);
    return EINA_TRUE;
 }
 
 static void
-_do(Client *c, char *op, unsigned char *d, int size)
+_process_command(void *data, const char op[static 4], const Eina_Slice payload)
 {
+   Client *c = data;
    Client *c2;
    Eina_List *l;
 
-   if ((!strcmp(op, "HELO")) && (size >= 8))
-     {
-        int version;
-        int pid;
+   DBG("client %p (%p) [pid:%d] op=%.4s payload=%zd", c, c->client, c->pid, 
op, payload.len);
 
-        fetch_val(version, d, 0);
-        fetch_val(pid, d, 4);
-        c->version = version;
-        c->pid = pid;
+   if (IS_OP(HELO))
+     {
+        if (payload.len < sizeof(int) * 2)
+          {
+             fprintf(stderr, "INFO: client %p [pid: %d] sent invalid HELO\n", 
c, (int)c->pid);
+             if (!efl_io_closer_closed_get(c->client))
+               efl_io_closer_close(c->client);
+          }
+        else
+          {
+             memcpy(&c->version, payload.bytes, sizeof(int));
+             memcpy(&c->pid, payload.bytes + sizeof(int), sizeof(int));
+             INF("client %p (%p) HELO version=%d, pid=%d", c, c->client, 
c->version, c->pid);
+          }
      }
-   else if (!strcmp(op, "LIST"))
+   else if (IS_OP(LIST))
      {
         int n = eina_list_count(clients);
         unsigned int *pids = malloc(n * sizeof(int));
@@ -85,177 +138,334 @@ _do(Client *c, char *op, unsigned char *d, int size)
 
              EINA_LIST_FOREACH(clients, l, c2)
                {
+                  if (c2->pid == 0) continue; /* no HELO yet */
                   pids[i] = c2->pid;
                   i++;
                }
-             send_cli(c->client, "CLST", pids, n * sizeof(int));
+             send_cli(c, CLST, pids, i * sizeof(int));
              free(pids);
           }
      }
-   else if ((!strcmp(op, "PLON")) && (size >= 8))
+   else if (IS_OP(PLON))
      {
-        int pid;
-        unsigned int freq = 1000;
-        fetch_val(pid, d, 0);
-        fetch_val(freq, d, 4);
-        if ((c2 = _client_pid_find(pid)))
+        if (payload.len < sizeof(int) * 2)
+          fprintf(stderr, "INFO: client %p [pid: %d] sent invalid PLON\n", c, 
(int)c->pid);
+        else
           {
-             unsigned char buf[4];
-             store_val(buf, 0, freq);
-             send_cli(c2->client, "PLON", buf, sizeof(buf));
+             int pid;
+             unsigned int freq;
+             memcpy(&pid, payload.bytes, sizeof(int));
+             memcpy(&freq, payload.bytes + sizeof(int), sizeof(int));
+             c2 = _client_pid_find(pid);
+             if (!c2)
+               {
+                  fprintf(stderr, "INFO: client %p [pid: %d] sent PLON %d: no 
such client\n", c, (int)c->pid, pid);
+               }
+             else
+               {
+                  DBG("client %p (%p) [pid:%d] requested PLON on %p (%p) 
[pid:%d]",
+                      c, c->client, c->pid,
+                      c2, c2->client, c2->pid);
+                  send_cli(c2, PLON, &freq, sizeof(freq));
+               }
           }
      }
-   else if (!strcmp(op, "PLOF"))
+   else if (IS_OP(PLOF))
      {
-        int pid;
-        fetch_val(pid, d, 0);
-        if ((c2 = _client_pid_find(pid)))
+        if (payload.len < sizeof(int))
+          fprintf(stderr, "INFO: client %p [pid: %d] sent invalid PLOF\n", c, 
(int)c->pid);
+        else
           {
-             send_cli(c2->client, "PLOF", NULL, 0);
+             int pid;
+             memcpy(&pid, payload.bytes, sizeof(int));
+             c2 = _client_pid_find(pid);
+             if (!c2)
+               {
+                  fprintf(stderr, "INFO: client %p [pid: %d] sent PLOF %d: no 
such client\n", c, (int)c->pid, pid);
+               }
+             else
+               {
+                  DBG("client %p (%p) [pid:%d] requested PLOF on %p (%p) 
[pid:%d]",
+                      c, c->client, c->pid,
+                      c2, c2->client, c2->pid);
+                  send_cli(c2, PLOF, NULL, 0);
+               }
           }
      }
-   else if (!strcmp(op, "EVON"))
+   else if (IS_OP(EVON))
      {
-        int pid;
-        fetch_val(pid, d, 0);
-        if ((c2 = _client_pid_find(pid)))
+        if (payload.len < sizeof(int))
+          fprintf(stderr, "INFO: client %p [pid: %d] sent invalid EVON\n", c, 
(int)c->pid);
+        else
           {
-             c2->evlog_on++;
-             if (c2->evlog_on == 1)
+             int pid;
+             memcpy(&pid, payload.bytes, sizeof(int));
+             c2 = _client_pid_find(pid);
+             if (!c2)
+               {
+                  fprintf(stderr, "INFO: client %p [pid: %d] sent EVON %d: no 
such client\n", c, (int)c->pid, pid);
+               }
+             else
                {
-                  char buf[4096];
+                  c2->evlog_on++;
+                  DBG("client %p (%p) [pid:%d] requested EVON (%d) on %p (%p) 
[pid:%d]",
+                      c, c->client, c->pid,
+                      c2->evlog_on,
+                      c2, c2->client, c2->pid);
+                  if (c2->evlog_on == 1)
+                    {
+                       char buf[4096];
 
-                  send_cli(c2->client, "EVON", NULL, 0);
-                  c2->evlog_fetch_timer = ecore_timer_add(0.2, _cb_evlog, c2);
-                  snprintf(buf, sizeof(buf), "%s/efl_debug_evlog-%ld.log",
-                           getenv("HOME"), (long)c2->pid);
-                  c2->evlog_file = fopen(buf, "wb");
+                       send_cli(c2, EVON, NULL, 0);
+                       c2->evlog_fetch_timer = ecore_timer_add(0.2, _cb_evlog, 
c2);
+                       snprintf(buf, sizeof(buf), "%s/efl_debug_evlog-%d.log",
+                                getenv("HOME"), c2->pid);
+                       c2->evlog_file = fopen(buf, "wb");
+                       DBG("client %p (%p) [pid:%d] logging to %s [%p]",
+                           c2, c2->client, c2->pid, buf, c2->evlog_file);
+                    }
                }
           }
      }
-   else if (!strcmp(op, "EVOF"))
+   else if (IS_OP(EVOF))
      {
-        int pid;
-        fetch_val(pid, d, 0);
-        if ((c2 = _client_pid_find(pid)))
+        if (payload.len < sizeof(int))
+          fprintf(stderr, "INFO: client %p [pid: %d] sent invalid EVOF\n", c, 
(int)c->pid);
+        else
           {
-             c2->evlog_on--;
-             if (c2->evlog_on == 0)
+             int pid;
+             memcpy(&pid, payload.bytes, sizeof(int));
+             c2 = _client_pid_find(pid);
+             if (!c2)
                {
-                  send_cli(c2->client, "EVOF", NULL, 0);
-                  if (c2->evlog_fetch_timer)
-                    {
-                       ecore_timer_del(c2->evlog_fetch_timer);
-                       c2->evlog_fetch_timer = NULL;
-                    }
-                  if (c2->evlog_file)
+                  fprintf(stderr, "INFO: client %p [pid: %d] sent EVOF %d: no 
such client\n", c, (int)c->pid, pid);
+               }
+             else
+               {
+                  c2->evlog_on--;
+                  DBG("client %p (%p) [pid:%d] requested EVOF (%d) on %p (%p) 
[pid:%d]",
+                      c, c->client, c->pid,
+                      c2->evlog_on,
+                      c2, c2->client, c2->pid);
+                  if (c2->evlog_on == 0)
                     {
-                       fclose(c2->evlog_file);
-                       c2->evlog_file = NULL;
+                       send_cli(c2, EVOF, NULL, 0);
+                       if (c2->evlog_fetch_timer)
+                         {
+                            ecore_timer_del(c2->evlog_fetch_timer);
+                            c2->evlog_fetch_timer = NULL;
+                         }
+                       if (c2->evlog_file)
+                         {
+                            DBG("client %p (%p) [pid:%d] finished logged to 
%p",
+                                c2, c2->client, c2->pid, c2->evlog_file);
+                            fclose(c2->evlog_file);
+                            c2->evlog_file = NULL;
+                         }
                     }
+                  else if (c2->evlog_on < 0)
+                    c2->evlog_on = 0;
                }
-             else if (c2->evlog_on < 0)
-               c2->evlog_on = 0;
           }
      }
-   else if (!strcmp(op, "EVLG"))
+   else if (IS_OP(EVLG))
      {
-        unsigned int *overflow = (unsigned int *)(d + 0);
-        unsigned char *p = d + 4;
-        unsigned int blocksize = size - 4;
-
-        if ((c->evlog_file) && (blocksize > 0))
+        if (payload.len < sizeof(int))
+          fprintf(stderr, "INFO: client %p [pid: %d] sent invalid EVLG\n", c, 
(int)c->pid);
+        else if (!c->evlog_file)
+          fprintf(stderr, "INFO: client %p [pid: %d] no matching EVON\n", c, 
(int)c->pid);
+        else
           {
-             unsigned int header[3];
+             unsigned int blocksize = payload.len - sizeof(int);
+             if (blocksize > 0)
+               {
+                  unsigned int header[3];
 
-             header[0] = 0xffee211;
-             header[1] = blocksize;
-             header[2] = *overflow;
-             fwrite(header, 12, 1, c->evlog_file);
-             fwrite(p, blocksize, 1, c->evlog_file);
+                  header[0] = 0xffee211;
+                  header[1] = blocksize;
+                  memcpy(header + 2, payload.mem, sizeof(int));
+
+                  fwrite(header, 12, 1, c->evlog_file);
+                  fwrite(payload.bytes + sizeof(int), blocksize, 1, 
c->evlog_file);
+               }
           }
      }
 }
 
-static Eina_Bool
-_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, 
Ecore_Con_Event_Client_Add *ev)
+static void
+_client_data(void *data, const Efl_Event *event)
 {
-   Client *c = calloc(1, sizeof(Client));
-   if (c)
+   Client *c = data;
+   if (!received_data(event->object, _process_command, c))
      {
-        c->client = ev->client;
-        clients = eina_list_append(clients, c);
-        ecore_con_client_data_set(c->client, c);
+        fprintf(stderr, "INFO: client %p [pid: %d] sent invalid data\n", c, 
(int)c->pid);
+        if (!efl_io_closer_closed_get(event->object))
+          efl_io_closer_close(event->object);
+        return;
      }
-   return ECORE_CALLBACK_RENEW;
 }
 
-static Eina_Bool
-_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, 
Ecore_Con_Event_Client_Del *ev)
+static void
+_client_error(void *data, const Efl_Event *event)
+{
+   Client *c = data;
+   Eina_Error *perr = event->info;
+   WRN("client %p [pid: %d] error: %s",
+       c, (int)c->pid, eina_error_msg_get(*perr));
+   fprintf(stderr, "INFO: client %p [pid: %d] error: %s\n",
+           c, (int)c->pid, eina_error_msg_get(*perr));
+}
+
+static void
+_client_eos(void *data, const Efl_Event *event EINA_UNUSED)
 {
-   Client *c = ecore_con_client_data_get(ev->client);
-   if (c)
+   Client *c = data;
+   DBG("client %p (%p) [pid: %d] closed, pending read %zu, write %zu",
+       c, c->client, (int)c->pid,
+       efl_io_buffered_stream_pending_read_get(c->client),
+       efl_io_buffered_stream_pending_write_get(c->client));
+   efl_io_closer_close(c->client);
+}
+
+static void
+_client_write_finished(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Client *c = data;
+   DBG("client %p (%p) [pid: %d] finished writing, pending read %zu",
+       c, c->client, (int)c->pid, 
efl_io_buffered_stream_pending_read_get(c->client));
+}
+
+static void
+_client_read_finished(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Client *c = data;
+   DBG("client %p (%p) [pid: %d] finished reading, pending write %zu",
+       c, c->client, (int)c->pid, 
efl_io_buffered_stream_pending_write_get(c->client));
+}
+
+static Efl_Callback_Array_Item *_client_cbs(void);
+
+static void
+_client_finished(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Client *c = data;
+
+   clients = eina_list_remove(clients, c);
+   if (c->evlog_fetch_timer)
      {
-        clients = eina_list_remove(clients, c);
-        if (c->evlog_fetch_timer)
-          {
-             ecore_timer_del(c->evlog_fetch_timer);
-             c->evlog_fetch_timer = NULL;
-          }
-        if (c->evlog_file)
-          {
-             fclose(c->evlog_file);
-             c->evlog_file = NULL;
-          }
-        free(c);
+        ecore_timer_del(c->evlog_fetch_timer);
+        c->evlog_fetch_timer = NULL;
+     }
+   if (c->evlog_file)
+     {
+        fclose(c->evlog_file);
+        c->evlog_file = NULL;
      }
-   return ECORE_CALLBACK_RENEW;
+   efl_event_callback_array_del(c->client, _client_cbs(), c);
+   INF("finished client %p (%p) [pid:%d]", c, c->client, c->pid);
+   efl_unref(c->client);
+   free(c);
 }
 
-static Eina_Bool
-_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, 
Ecore_Con_Event_Client_Data *ev)
+EFL_CALLBACKS_ARRAY_DEFINE(_client_cbs,
+                           { EFL_IO_READER_EVENT_EOS, _client_eos },
+                           { EFL_IO_BUFFERED_STREAM_EVENT_ERROR, _client_error 
},
+                           { EFL_IO_BUFFERED_STREAM_EVENT_READ_FINISHED, 
_client_read_finished },
+                           { EFL_IO_BUFFERED_STREAM_EVENT_WRITE_FINISHED, 
_client_write_finished },
+                           { EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, 
_client_finished },
+                           { EFL_IO_BUFFERED_STREAM_EVENT_SLICE_CHANGED, 
_client_data });
+
+static void
+_client_add(void *data EINA_UNUSED, const Efl_Event *event)
 {
-   Client *c = ecore_con_client_data_get(ev->client);
-   if (c)
-     {
-        char op[5];
-        unsigned char *d = NULL;
-        int size;
+   Client *c = calloc(1, sizeof(Client));
 
-        _protocol_collect(&(c->buf), &(c->buf_size), ev->data, ev->size);
-        while ((size = _proto_read(&(c->buf), &(c->buf_size), op, &d)) >= 0)
-          {
-             _do(c, op, d, size);
-             free(d);
-             d = NULL;
-          }
-     }
-   return ECORE_CALLBACK_RENEW;
+   EINA_SAFETY_ON_NULL_RETURN(c);
+   c->client = efl_ref(event->info);
+   clients = eina_list_append(clients, c);
+   efl_event_callback_array_add(c->client, _client_cbs(), c);
+   INF("server %p new client %p (%p)", event->object, c, c->client);
+}
+
+static void
+_error(void *data EINA_UNUSED, const Efl_Event *event)
+{
+   Eina_Error *perr = event->info;
+   ERR("server %p error: %s", event->object, eina_error_msg_get(*perr));
+   fprintf(stderr, "ERROR: %s\n", eina_error_msg_get(*perr));
+   ecore_main_loop_quit();
+   retval = EXIT_FAILURE;
 }
 
 int
 main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
 {
+   Eo *loop;
+   char *path;
+   Eina_Error err;
+
+   ecore_app_no_system_modules();
+
    eina_init();
    ecore_init();
    ecore_con_init();
 
-   svr = ecore_con_server_add(ECORE_CON_LOCAL_USER, "efl_debug", 0, NULL);
-   if (!svr)
+   _log_dom = eina_log_domain_register("efl_debugd", EINA_COLOR_CYAN);
+
+   path = ecore_con_local_path_new(EINA_FALSE, "efl_debug", 0);
+   if (!path)
+     {
+        fprintf(stderr, "ERROR: could not get local communication path\n");
+        retval = EXIT_FAILURE;
+        goto end;
+     }
+
+   loop = ecore_main_loop_get();
+
+#ifdef EFL_NET_SERVER_UNIX_CLASS
+   server = efl_add(EFL_NET_SERVER_SIMPLE_CLASS, loop,
+                    efl_net_server_simple_inner_class_set(efl_added, 
EFL_NET_SERVER_UNIX_CLASS));
+#else
+   /* TODO: maybe start a TCP using locahost:12345?
+    * Right now eina_debug_monitor is only for AF_UNIX, so not an issue.
+    */
+   fprintf(stderr, "ERROR: your platform doesn't support 
Efl.Net.Server.Unix\n");
+#endif
+   if (!server)
      {
-        fprintf(stderr, "ERROR: Cannot create debug daemon.\n");
-        return -1;
+        fprintf(stderr, "ERROR: could not create communication server\n");
+        retval = EXIT_FAILURE;
+        goto end;
      }
 
-   ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, 
(Ecore_Event_Handler_Cb)_client_add, NULL);
-   ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, 
(Ecore_Event_Handler_Cb)_client_del, NULL);
-   ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, 
(Ecore_Event_Handler_Cb)_client_data, NULL);
+   efl_event_callback_add(server, EFL_NET_SERVER_EVENT_CLIENT_ADD, 
_client_add, NULL);
+   efl_event_callback_add(server, EFL_NET_SERVER_EVENT_ERROR, _error, NULL);
+
+#ifdef EFL_NET_SERVER_UNIX_CLASS
+   {
+      Eo *inner_server = efl_net_server_simple_inner_server_get(server);
+      efl_net_server_unix_unlink_before_bind_set(inner_server, EINA_TRUE);
+      efl_net_server_unix_leading_directories_create_set(inner_server, 
EINA_TRUE, 0700);
+   }
+#endif
+
+   err = efl_net_server_serve(server, path);
+   if (err)
+     {
+        fprintf(stderr, "ERROR: could not serve '%s': %s\n", path, 
eina_error_msg_get(err));
+        retval = EXIT_FAILURE;
+        goto end;
+     }
 
    ecore_main_loop_begin();
 
-   ecore_con_server_del(svr);
+ end:
+   efl_del(server);
+   free(path);
 
    ecore_con_shutdown();
    ecore_shutdown();
    eina_shutdown();
+
+   return retval;
 }

-- 


Reply via email to