diff --git a/src/bin/efl/efl_debug.c b/src/bin/efl/efl_debug.c index 5c0ee959c0..177dfa9572 100644 --- a/src/bin/efl/efl_debug.c +++ b/src/bin/efl/efl_debug.c @@ -16,8 +16,6 @@ * if not, see . */ -#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 1ef29675dd..7776d78816 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 29e9739c7f..fdb9e45dbe 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 #include #include @@ -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 a07fe3fcee..1934c81979 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)); - } - } - else if (!strcmp(op, "PLOF")) - { - int pid; - fetch_val(pid, d, 0); - if ((c2 = _client_pid_find(pid))) - { - send_cli(c2->client, "PLOF", NULL, 0); - } - } - else if (!strcmp(op, "EVON")) - { - int pid; - fetch_val(pid, d, 0); - if ((c2 = _client_pid_find(pid))) - { - c2->evlog_on++; - if (c2->evlog_on == 1) + 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) { - 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"); + 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, "EVOF")) + 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 { - 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) - { - fclose(c2->evlog_file); - c2->evlog_file = NULL; - } + 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 (c2->evlog_on < 0) - c2->evlog_on = 0; } } - else if (!strcmp(op, "EVLG")) + else if (IS_OP(EVON)) { - 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 EVON\n", c, (int)c->pid); + else { - unsigned int header[3]; + 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 + { + 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]; - header[0] = 0xffee211; - header[1] = blocksize; - header[2] = *overflow; - fwrite(header, 12, 1, c->evlog_file); - fwrite(p, blocksize, 1, c->evlog_file); + 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 (IS_OP(EVOF)) + { + if (payload.len < sizeof(int)) + fprintf(stderr, "INFO: client %p [pid: %d] sent invalid EVOF\n", c, (int)c->pid); + else + { + int pid; + memcpy(&pid, payload.bytes, sizeof(int)); + c2 = _client_pid_find(pid); + if (!c2) + { + 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) + { + 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 (IS_OP(EVLG)) + { + 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 blocksize = payload.len - sizeof(int); + if (blocksize > 0) + { + unsigned int header[3]; + + 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 = data; + if (!received_data(event->object, _process_command, 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; + } +} + +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 = 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) + { + ecore_timer_del(c->evlog_fetch_timer); + c->evlog_fetch_timer = NULL; + } + if (c->evlog_file) + { + fclose(c->evlog_file); + c->evlog_file = NULL; + } + 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); +} + +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 = calloc(1, sizeof(Client)); - if (c) - { - c->client = ev->client; - clients = eina_list_append(clients, c); - ecore_con_client_data_set(c->client, c); - } - 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 Eina_Bool -_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Client_Del *ev) +static void +_error(void *data EINA_UNUSED, const Efl_Event *event) { - Client *c = ecore_con_client_data_get(ev->client); - if (c) - { - 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); - } - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Client_Data *ev) -{ - Client *c = ecore_con_client_data_get(ev->client); - if (c) - { - char op[5]; - unsigned char *d = NULL; - int size; - - _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_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: Cannot create debug daemon.\n"); - return -1; + fprintf(stderr, "ERROR: could not get local communication path\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); + 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: could not create communication server\n"); + retval = EXIT_FAILURE; + goto end; + } + + 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; }