summaryrefslogtreecommitdiff
path: root/src/bin/efl
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@yahoo.com>2017-06-09 01:25:52 +0300
committerDaniel Zaoui <daniel.zaoui@yahoo.com>2017-06-11 09:44:57 +0300
commitae50dec3e57fc38d3f0f23eb8d5377a05ab38e14 (patch)
tree50f69205c96868d18f9d3e5462a1d28cc1e1314f /src/bin/efl
parent0e947166aa8e9e09e5d61a0eef2857fd522e8924 (diff)
Eina Debug: rewrite efl_debugd for portability
The previous version of the daemon was using functions specific to Linux, such as epoll... The daemon communication part has been rewritten to use Ecore functionalities. Sorry for the inconvenience guys
Diffstat (limited to 'src/bin/efl')
-rw-r--r--src/bin/efl/efl_debugd.c575
1 files changed, 308 insertions, 267 deletions
diff --git a/src/bin/efl/efl_debugd.c b/src/bin/efl/efl_debugd.c
index 98db8453d8..cfd83e13ae 100644
--- a/src/bin/efl/efl_debugd.c
+++ b/src/bin/efl/efl_debugd.c
@@ -20,29 +20,41 @@
20# include <config.h> 20# include <config.h>
21#endif 21#endif
22 22
23#include <unistd.h> 23#define EFL_BETA_API_SUPPORT 1
24#ifdef HAVE_SYS_EPOLL_H 24#define EFL_EO_API_SUPPORT 1
25# include <sys/epoll.h> 25
26#endif
27#include <sys/types.h>
28#ifdef HAVE_SYS_SOCKET_H
29# include <sys/socket.h>
30#endif
31#ifdef HAVE_SYS_UN_H
32# include <sys/un.h>
33#endif
34#ifdef HAVE_NETINET_IN_H
35# include <netinet/in.h>
36#endif
37#ifdef HAVE_ARPA_INET_H
38# include <arpa/inet.h>
39#endif
40#include <fcntl.h> 26#include <fcntl.h>
41#include "eina_debug_private.h" 27#include "eina_debug_private.h"
42 28
43#include <Eina.h> 29#include <Eina.h>
44#include <Ecore.h> 30#include <Ecore.h>
31#include <Ecore_Con.h>
32
33static int _log_dom = -1;
34#ifdef ERR
35# undef ERR
36#endif
37#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
38
39#ifdef DBG
40# undef DBG
41#endif
42#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
45 43
44#ifdef INF
45# undef INF
46#endif
47#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
48
49#ifdef WRN
50# undef WRN
51#endif
52#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
53
54#ifdef CRI
55# undef CRI
56#endif
57#define CRI(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
46#if __BYTE_ORDER == __LITTLE_ENDIAN 58#if __BYTE_ORDER == __LITTLE_ENDIAN
47#define SWAP_64(x) x 59#define SWAP_64(x) x
48#define SWAP_32(x) x 60#define SWAP_32(x) x
@@ -69,10 +81,10 @@ typedef struct _Client Client;
69 81
70struct _Client 82struct _Client
71{ 83{
84 Eo * client;
72 Eina_Stringshare *app_name; 85 Eina_Stringshare *app_name;
73 86
74 int version; 87 int version;
75 int fd;
76 int cid; 88 int cid;
77 pid_t pid; 89 pid_t pid;
78 90
@@ -81,6 +93,9 @@ struct _Client
81}; 93};
82 94
83static Eina_List *_clients = NULL; 95static Eina_List *_clients = NULL;
96static int _retval;
97
98static Eo *_local_server = NULL, *_remote_server = NULL;
84 99
85typedef Eina_Bool (*Opcode_Cb)(Client *client, void *buffer, int size); 100typedef Eina_Bool (*Opcode_Cb)(Client *client, void *buffer, int size);
86 101
@@ -104,11 +119,6 @@ typedef struct
104#define MAX_OPCODES 1000 119#define MAX_OPCODES 1000
105Opcode_Information *_opcodes[MAX_OPCODES]; 120Opcode_Information *_opcodes[MAX_OPCODES];
106 121
107/* epoll stuff */
108#ifndef _WIN32
109static int _epfd = -1, _listening_unix_fd = -1, _listening_tcp_fd = -1;
110#endif
111
112static Client * 122static Client *
113_client_find_by_cid(int cid) 123_client_find_by_cid(int cid)
114{ 124{
@@ -129,54 +139,48 @@ _client_find_by_pid(int pid)
129 return NULL; 139 return NULL;
130} 140}
131 141
132static Client *
133_client_find_by_fd(int fd)
134{
135 Eina_List *itr;
136 Client *c;
137 EINA_LIST_FOREACH(_clients, itr, c)
138 if (c->fd == fd) return c;
139 return NULL;
140}
141
142static void 142static void
143_send(Client *dest, int opcode, void *payload, int payload_size) 143_send(Client *dest, int opcode, void *payload, int payload_size)
144{ 144{
145 Eina_Error err;
146 Eina_Slice s, r;
147 Eina_Debug_Packet_Header hdr;
145 int size = sizeof(Eina_Debug_Packet_Header) + payload_size; 148 int size = sizeof(Eina_Debug_Packet_Header) + payload_size;
146 char *buf = alloca(size);
147 Eina_Debug_Packet_Header *hdr = (Eina_Debug_Packet_Header *)buf;
148 hdr->size = SWAP_32(size);
149 hdr->cid = 0;
150 hdr->opcode = SWAP_32(opcode);
151 memcpy(buf + sizeof(Eina_Debug_Packet_Header), payload, payload_size);
152 printf("Send packet (size = %d, opcode %s) to %s\n", size,
153 _opcodes[hdr->opcode]->opcode_string,
154 dest->app_name);
155 if (send(dest->fd, buf, size, 0) != size) perror("send");
156}
157 149
158static void 150 hdr.size = SWAP_32(size);
159_client_del(Client *c) 151 hdr.cid = 0;
160{ 152 hdr.opcode = SWAP_32(opcode);
161 Client *c2;
162 if (!c) return;
163 Eina_List *itr;
164 153
165 _clients = eina_list_remove(_clients, c); 154 s.mem = &hdr;
155 s.len = sizeof(hdr);
166 156
167 /* Don't update the observers if the client is a master */ 157 err = efl_io_writer_write(dest->client, &s, &r);
168 if (c->is_master) return; 158 if (err || r.len) goto end;
169 159
170 EINA_LIST_FOREACH(_clients, itr, c2) 160 if (!payload_size) goto end;
161
162 s.mem = payload;
163 s.len = payload_size;
164 err = efl_io_writer_write(dest->client, &s, &r);
165
166 INF("Send packet (size = %d, opcode %s) to %s", size,
167 _opcodes[opcode]->opcode_string,
168 dest->app_name);
169
170 end:
171 if (err)
171 { 172 {
172 int cid = SWAP_32(c->cid); 173 fprintf(stderr, "ERROR: could not queue message '%d': %s\n", opcode, eina_error_msg_get(err));
173 if (c2->cl_stat_obs) _send(c2, _slave_deleted_opcode, &cid, sizeof(int)); 174 }
175
176 if (r.len)
177 {
178 fprintf(stderr, "ERROR: could not queue message '%d': out of memory\n", opcode);
174 } 179 }
175 free(c);
176} 180}
177 181
178static Eina_Bool 182static Eina_Bool
179_dispatch(Client *src, void *buffer, unsigned int size) 183_dispatch(Client *src, void *buffer)
180{ 184{
181 Eina_Debug_Packet_Header *hdr = (Eina_Debug_Packet_Header *)buffer; 185 Eina_Debug_Packet_Header *hdr = (Eina_Debug_Packet_Header *)buffer;
182 if (hdr->cid) 186 if (hdr->cid)
@@ -187,9 +191,14 @@ _dispatch(Client *src, void *buffer, unsigned int size)
187 { 191 {
188 if (dest->is_master != src->is_master) 192 if (dest->is_master != src->is_master)
189 { 193 {
194 Eina_Slice s;
195 s.mem = buffer;
196 s.len = hdr->size;
190 hdr->cid = SWAP_32(src->cid); 197 hdr->cid = SWAP_32(src->cid);
191 if (send(dest->fd, buffer, size, 0) != size) perror("send"); 198 hdr->size = SWAP_32(hdr->size);
192 printf("Transfer of %d bytes from %s(%d) to %s(%d): operation %s\n", 199 hdr->opcode = SWAP_32(hdr->opcode);
200 efl_io_writer_write(dest->client, &s, NULL);
201 INF("Transfer of %d bytes from %s(%d) to %s(%d): operation %s\n",
193 hdr->size, 202 hdr->size,
194 src->app_name, src->pid, 203 src->app_name, src->pid,
195 dest->app_name, dest->pid, 204 dest->app_name, dest->pid,
@@ -201,16 +210,17 @@ _dispatch(Client *src, void *buffer, unsigned int size)
201 * Packets Master -> Master or Slave -> Slave are forbidden 210 * Packets Master -> Master or Slave -> Slave are forbidden
202 * Only Master <-> Slave packets are allowed. 211 * Only Master <-> Slave packets are allowed.
203 */ 212 */
204 printf("Packet from %d to %d: denied (same type)\n", hdr->cid, dest->cid); 213 ERR("Packet from %d to %d: denied (same type)\n", hdr->cid, dest->cid);
205 } 214 }
206 } 215 }
207 } 216 }
208 else 217 else
209 { 218 {
210 printf("Invoke %s\n", _opcodes[hdr->opcode]->opcode_string); 219 INF("Invoke %s\n", _opcodes[hdr->opcode]->opcode_string);
211 if (_opcodes[hdr->opcode]->cb) 220 if (_opcodes[hdr->opcode]->cb)
212 return _opcodes[hdr->opcode]->cb(src, 221 return _opcodes[hdr->opcode]->cb(src,
213 (char *)buffer + sizeof(Eina_Debug_Packet_Header), size - sizeof(Eina_Debug_Packet_Header)); 222 (char *)buffer + sizeof(Eina_Debug_Packet_Header),
223 hdr->size - sizeof(Eina_Debug_Packet_Header));
214 } 224 }
215 return EINA_TRUE; 225 return EINA_TRUE;
216} 226}
@@ -238,7 +248,7 @@ _opcode_register(const char *op_name, int op_id, Opcode_Cb cb)
238 eina_hash_add(_string_to_opcode_hash, op_name, op_info); 248 eina_hash_add(_string_to_opcode_hash, op_name, op_info);
239 _opcodes[op_id] = op_info; 249 _opcodes[op_id] = op_info;
240 } 250 }
241 printf("Register %s -> opcode %d\n", op_name, op_info->opcode); 251 INF("Register %s -> opcode %d\n", op_name, op_info->opcode);
242 return op_info->opcode; 252 return op_info->opcode;
243} 253}
244 254
@@ -261,7 +271,7 @@ _hello_cb(Client *c, void *buffer, int size)
261 { 271 {
262 c->app_name = eina_stringshare_add_length(buf, size); 272 c->app_name = eina_stringshare_add_length(buf, size);
263 } 273 }
264 printf("Connection of %s: pid %d - name %s -> cid %d\n", 274 INF("Connection of %s: pid %d - name %s -> cid %d\n",
265 c->is_master ? "Master" : "Slave", 275 c->is_master ? "Master" : "Slave",
266 c->pid, c->app_name, c->cid); 276 c->pid, c->app_name, c->cid);
267 277
@@ -302,7 +312,7 @@ _cid_get_cb(Client *src, void *buffer, int size EINA_UNUSED)
302static Eina_Bool 312static Eina_Bool
303_data_test_cb(Client *src, void *buffer, int size) 313_data_test_cb(Client *src, void *buffer, int size)
304{ 314{
305 printf("Data test: loop packet of %d bytes\n", size); 315 DBG("Data test: loop packet of %d bytes\n", size);
306 _send(src, _test_loop_opcode, buffer, size); 316 _send(src, _test_loop_opcode, buffer, size);
307 return EINA_TRUE; 317 return EINA_TRUE;
308} 318}
@@ -369,133 +379,150 @@ _opcode_register_cb(Client *src, void *buffer, int size)
369 return EINA_TRUE; 379 return EINA_TRUE;
370} 380}
371 381
372static int 382static void
373_data_receive(Client *c, unsigned char *buffer) 383_client_data(void *data, const Efl_Event *event)
374{ 384{
375 int rret; 385 static unsigned char *buffer = NULL;
376 unsigned int size = 0; 386 unsigned int size = 0;
387 Eina_Debug_Packet_Header *hdr;
388 Client *c = data;
389 Eina_Slice slice;
377 390
378 if (!c) return -1; 391 if (!c) return;
392
393 if (!buffer) buffer = malloc(EINA_DEBUG_MAX_PACKET_SIZE);
394
395 slice = efl_io_buffered_stream_slice_get(c->client);
379 396
380 rret = recv(c->fd, &size, sizeof(int), MSG_PEEK); 397 if (slice.len < sizeof(*hdr)) return;
381 398
382 if (rret == -1 || !size) goto error; 399 hdr = (Eina_Debug_Packet_Header *)slice.mem;
383 if (rret == sizeof(int)) 400 size = SWAP_32(hdr->size);
401 if (size < sizeof(*hdr)) /* must contain at least the header */
384 { 402 {
385 Eina_Debug_Packet_Header *hdr; 403 fprintf(stderr, "ERROR: invalid message header, size=%u\n", hdr->size);
386 unsigned int cur_packet_size = 0; 404 goto err;
387 size = SWAP_32(size);
388 if (size > EINA_DEBUG_MAX_PACKET_SIZE) goto error;
389 while (cur_packet_size < size)
390 {
391 rret = recv(c->fd, buffer + cur_packet_size, size - cur_packet_size, 0);
392 if (rret <= 0) goto error;
393 cur_packet_size += rret;
394 }
395 hdr = (Eina_Debug_Packet_Header *) buffer;
396 hdr->size = SWAP_32(hdr->size);
397 hdr->opcode = SWAP_32(hdr->opcode);
398 hdr->cid = SWAP_32(hdr->cid);
399 } 405 }
400 //printf("%d bytes received from client %s fd %d\n", size, c->app_name, c->fd); 406
401 return size; 407 if (size > EINA_DEBUG_MAX_PACKET_SIZE)
402error: 408 {
403 if (rret == -1) perror("Read from socket"); 409 fprintf(stderr, "ERROR: packet too big (max: %d), size=%u\n",
404 return -1; 410 EINA_DEBUG_MAX_PACKET_SIZE, hdr->size);
411 goto err;
412 }
413
414 /* Incomplete packet: need to wait */
415 if (size > slice.len) return;
416
417 memcpy(buffer, slice.mem, size);
418 hdr = (Eina_Debug_Packet_Header *)buffer;
419 hdr->size = SWAP_32(hdr->size);
420 hdr->opcode = SWAP_32(hdr->opcode);
421 hdr->cid = SWAP_32(hdr->cid);
422
423 if(!_dispatch(c, buffer))
424 {
425 // something we don't understand
426 fprintf(stderr, "Dispatch: unknown command: %d\n", hdr->opcode);
427 }
428 efl_io_buffered_stream_discard(c->client, size);
429 return;
430err:
431 if (!efl_io_closer_closed_get(event->object))
432 efl_io_closer_close(event->object);
433 fprintf(stderr, "INFO: client %p [pid: %d] sent invalid data\n", c, (int)c->pid);
405} 434}
406 435
407static void 436static void
408_monitor(void) 437_client_error(void *data, const Efl_Event *event)
409{ 438{
410#ifndef _WIN32 439 Client *c = data;
411#define MAX_EVENTS 1000 440 Eina_Error *perr = event->info;
412 int ret = 0; 441 WRN("client %p [pid: %d] error: %s",
413 struct epoll_event events[MAX_EVENTS]; 442 c, (int)c->pid, eina_error_msg_get(*perr));
414 unsigned char *buffer = malloc(EINA_DEBUG_MAX_PACKET_SIZE); 443 fprintf(stderr, "INFO: client %p [pid: %d] error: %s\n",
415 Client *c; 444 c, (int)c->pid, eina_error_msg_get(*perr));
445}
416 446
417 // sit forever processing commands or timeouts 447static void
418 for (; ret != -1;) 448_client_eos(void *data, const Efl_Event *event EINA_UNUSED)
419 { 449{
420 ret = epoll_wait (_epfd, events, MAX_EVENTS, -1); 450 Client *c = data;
451 DBG("client %p (%p) [pid: %d] closed, pending read %zu, write %zu",
452 c, c->client, (int)c->pid,
453 efl_io_buffered_stream_pending_read_get(c->client),
454 efl_io_buffered_stream_pending_write_get(c->client));
455 efl_io_closer_close(c->client);
456}
421 457
422 // if the fd for debug daemon says it's alive, process it 458static void
423 if (ret > 0) 459_client_write_finished(void *data, const Efl_Event *event EINA_UNUSED)
424 { 460{
425 int i; 461 Client *c = data;
426 //check which fd are set/ready for read 462 DBG("client %p (%p) [pid: %d] finished writing, pending read %zu",
427 for (i = 0; i < ret; i++) 463 c, c->client, (int)c->pid, efl_io_buffered_stream_pending_read_get(c->client));
428 { 464}
429 if (events[i].events & EPOLLHUP) 465
430 { 466static void
431 c = _client_find_by_fd(events[i].data.fd); 467_client_read_finished(void *data, const Efl_Event *event EINA_UNUSED)
432 close(events[i].data.fd); 468{
433 if (c) 469 Client *c = data;
434 { 470 DBG("client %p (%p) [pid: %d] finished reading, pending write %zu",
435 printf("Closing client %s/%d\n", c->app_name, c->pid); 471 c, c->client, (int)c->pid, efl_io_buffered_stream_pending_write_get(c->client));
436 _client_del(c); 472}
437 } 473
438 } 474static Efl_Callback_Array_Item *_client_cbs(void);
439 if (events[i].events & EPOLLIN) 475
440 { 476static void
441 // Someone wants to connect 477_client_finished(void *data, const Efl_Event *event EINA_UNUSED)
442 if(events[i].data.fd == _listening_unix_fd || events[i].data.fd == _listening_tcp_fd) 478{
443 { 479 Eina_List *itr;
444 int new_fd = accept(events[i].data.fd, NULL, NULL); 480 Client *c = data, *c2;
445 if (new_fd < 0) perror("Accept"); 481 int cid = SWAP_32(c->cid);
446 else 482 efl_event_callback_array_del(c->client, _client_cbs(), c);
447 { 483 INF("finished client %p (%p) [pid:%d]", c, c->client, c->pid);
448 struct epoll_event event; 484 _clients = eina_list_remove(_clients, c);
449 c = calloc(1, sizeof(*c)); 485 efl_unref(c->client);
450 c->fd = new_fd; 486
451 c->is_master = (events[i].data.fd == _listening_tcp_fd); 487 /* Don't update the observers if the client is a master */
452 _clients = eina_list_append(_clients, c); 488 if (c->is_master) return;
453 event.data.fd = new_fd; 489
454 event.events = EPOLLIN; 490 EINA_LIST_FOREACH(_clients, itr, c2)
455 epoll_ctl (_epfd, EPOLL_CTL_ADD, new_fd, &event); 491 {
456 } 492 if (c2->cl_stat_obs) _send(c2, _slave_deleted_opcode, &cid, sizeof(int));
457 continue;
458 }
459
460 c = _client_find_by_fd(events[i].data.fd);
461 if (c)
462 {
463 int size;
464 size = _data_receive(c, buffer);
465 // if not negative - we have a real message
466 if (size >= 0)
467 {
468 if(!_dispatch(c, buffer, size))
469 {
470 // something we don't understand
471 fprintf(stderr, "Dispatch: unknown command");
472 }
473 }
474 else
475 {
476 // major failure on debug daemon control fd - get out of here.
477 // else goto fail;
478 close(events[i].data.fd);
479 _client_del(c);
480 //TODO if its not main session we will tell the main_loop
481 //that it disconneted
482 }
483 }
484 }
485 }
486 }
487#if 0
488 else
489 {
490 if (poll_time && poll_timer_cb)
491 {
492 if (!poll_timer_cb()) poll_time = 0;
493 }
494 }
495#endif
496 } 493 }
497 free(buffer); 494 free(c);
498#endif 495}
496
497EFL_CALLBACKS_ARRAY_DEFINE(_client_cbs,
498 { EFL_IO_READER_EVENT_EOS, _client_eos },
499 { EFL_IO_BUFFERED_STREAM_EVENT_ERROR, _client_error },
500 { EFL_IO_BUFFERED_STREAM_EVENT_READ_FINISHED, _client_read_finished },
501 { EFL_IO_BUFFERED_STREAM_EVENT_WRITE_FINISHED, _client_write_finished },
502 { EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, _client_finished },
503 { EFL_IO_BUFFERED_STREAM_EVENT_SLICE_CHANGED, _client_data });
504
505static void
506_client_add(void *data EINA_UNUSED, const Efl_Event *event)
507{
508 Client *c = calloc(1, sizeof(Client));
509
510 EINA_SAFETY_ON_NULL_RETURN(c);
511 c->client = efl_ref(event->info);
512 c->is_master = (event->object == _remote_server);
513 _clients = eina_list_append(_clients, c);
514 efl_event_callback_array_add(c->client, _client_cbs(), c);
515 INF("server %p new client %p (%p)", event->object, c, c->client);
516}
517
518static void
519_error(void *data EINA_UNUSED, const Efl_Event *event)
520{
521 Eina_Error *perr = event->info;
522 ERR("server %p error: %s", event->object, eina_error_msg_get(*perr));
523 fprintf(stderr, "ERROR: %s\n", eina_error_msg_get(*perr));
524 ecore_main_loop_quit();
525 _retval = EXIT_FAILURE;
499} 526}
500 527
501static char * 528static char *
@@ -514,127 +541,134 @@ _socket_home_get(void)
514 return ret; 541 return ret;
515} 542}
516 543
517#ifndef _WIN32 544static Eina_Bool
518#define LENGTH_OF_SOCKADDR_UN(s) \ 545_local_server_create(void)
519 (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
520static int
521_listening_unix_socket_create(void)
522{ 546{
523 char buf[1048]; 547 Eo *loop;
524 struct sockaddr_un socket_unix; 548 Eina_Error err;
525 int socket_unix_len, curstate = 0;
526 char *socket_path = _socket_home_get(); 549 char *socket_path = _socket_home_get();
527 mode_t mask = 0; 550 mode_t mask = 0;
528 // create the socket 551 char path[512];
529 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
530 Eina_Bool ret = EINA_FALSE; 552 Eina_Bool ret = EINA_FALSE;
531 553
532 if (fd < 0) goto end; 554 snprintf(path, sizeof(path) - 1, "%s/%s", socket_path, LOCAL_SERVER_PATH);
533 // set the socket to close when we exec things so they don't inherit it 555 if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST)
534 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) goto end;
535 // set up some socket options on addr re-use
536 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
537 sizeof(curstate)) < 0)
538 goto end;
539
540 snprintf(buf, sizeof(buf) - 1, "%s/%s", socket_path, LOCAL_SERVER_PATH);
541 if (mkdir(buf, S_IRWXU) < 0 && errno != EEXIST)
542 { 556 {
543 perror("mkdir SERVER_PATH"); 557 perror("mkdir SERVER_PATH");
544 goto end; 558 goto end;
545 } 559 }
546 snprintf(buf, sizeof(buf) - 1, "%s/%s/%s", socket_path, LOCAL_SERVER_PATH, LOCAL_SERVER_NAME); 560 snprintf(path, sizeof(path) - 1, "%s/%s/%s", socket_path, LOCAL_SERVER_PATH, LOCAL_SERVER_NAME);
547 if (mkdir(buf, S_IRWXU) < 0 && errno != EEXIST) 561 if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST)
548 { 562 {
549 perror("mkdir SERVER_NAME"); 563 perror("mkdir SERVER_NAME");
550 goto end; 564 goto end;
551 } 565 }
552 mask = umask(S_IRWXG | S_IRWXO); 566 mask = umask(S_IRWXG | S_IRWXO);
553 snprintf(buf, sizeof(buf) - 1, "%s/%s/%s/%i", socket_path, 567 snprintf(path, sizeof(path) - 1, "%s/%s/%s/%i", socket_path,
554 LOCAL_SERVER_PATH, LOCAL_SERVER_NAME, LOCAL_SERVER_PORT); 568 LOCAL_SERVER_PATH, LOCAL_SERVER_NAME, LOCAL_SERVER_PORT);
555 // sa that it's a unix socket and where the path is 569
556 socket_unix.sun_family = AF_UNIX; 570 loop = ecore_main_loop_get();
557 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path) - 1); 571
558 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix); 572#ifdef EFL_NET_SERVER_UNIX_CLASS
559 unlink(socket_unix.sun_path); 573 _local_server = efl_add(EFL_NET_SERVER_SIMPLE_CLASS, loop,
560 if (bind(fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) 574 efl_net_server_simple_inner_class_set(efl_added, EFL_NET_SERVER_UNIX_CLASS));
575#else
576 /* TODO: maybe start a TCP using locahost:12345?
577 * Right now eina_debug_monitor is only for AF_UNIX, so not an issue.
578 */
579 fprintf(stderr, "ERROR: your platform doesn't support Efl.Net.Server.Unix\n");
580#endif
581 if (!_local_server)
561 { 582 {
562 perror("ERROR on binding"); 583 fprintf(stderr, "ERROR: could not create communication server\n");
584 goto end;
585 }
586
587 efl_event_callback_add(_local_server, EFL_NET_SERVER_EVENT_CLIENT_ADD, _client_add, NULL);
588 efl_event_callback_add(_local_server, EFL_NET_SERVER_EVENT_ERROR, _error, NULL);
589
590#ifdef EFL_NET_SERVER_UNIX_CLASS
591 {
592 Eo *inner_server = efl_net_server_simple_inner_server_get(_local_server);
593 efl_net_server_unix_unlink_before_bind_set(inner_server, EINA_TRUE);
594 efl_net_server_unix_leading_directories_create_set(inner_server, EINA_TRUE, 0700);
595 }
596#endif
597
598 err = efl_net_server_serve(_local_server, path);
599 if (err)
600 {
601 fprintf(stderr, "ERROR: could not serve '%s': %s\n", path, eina_error_msg_get(err));
563 goto end; 602 goto end;
564 } 603 }
565 listen(fd, 5);
566 ret = EINA_TRUE; 604 ret = EINA_TRUE;
567end: 605end:
568 umask(mask); 606 umask(mask);
569 if (!ret && fd >= 0) 607 if (!ret)
570 { 608 {
571 close(fd); 609 efl_del(_local_server);
572 fd = -1; 610 _local_server = NULL;
573 } 611 }
574 free(socket_path); 612 free(socket_path);
575 return fd; 613 return ret;
576} 614}
577#endif
578 615
579static int 616static Eina_Bool
580_listening_tcp_socket_create(void) 617_remote_server_create(void)
581{ 618{
582 struct sockaddr_in server; 619 Eo *loop;
583 int curstate = 1; 620 Eina_Error err;
584 // create the socket 621 mode_t mask = 0;
585 int fd = socket(AF_INET, SOCK_STREAM, 0); 622 Eina_Bool ret = EINA_FALSE;
586 if (fd < 0) goto err; 623 char address[256];
587 // set the socket to close when we exec things so they don't inherit it 624
588 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) goto err; 625 loop = ecore_main_loop_get();
589 // set up some socket options on addr re-use 626
590 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, 627 _remote_server = efl_add(EFL_NET_SERVER_SIMPLE_CLASS, loop,
591 sizeof(curstate)) < 0) 628 efl_net_server_simple_inner_class_set(efl_added, EFL_NET_SERVER_TCP_CLASS));
592 goto err; 629 if (!_remote_server)
593
594 //Prepare the sockaddr_in structure
595 memset(&server, 0, sizeof(server));
596 server.sin_family = AF_INET;
597 inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr);
598 server.sin_port = htons(REMOTE_SERVER_PORT);
599
600 if (bind(fd, (struct sockaddr *)&server, sizeof(server)) < 0)
601 { 630 {
602 perror("ERROR on binding"); 631 fprintf(stderr, "ERROR: could not create communication server\n");
603 goto err; 632 goto end;
604 } 633 }
605 listen(fd, 5); 634
606 return fd; 635 {
607err: 636 Eo *inner_server = efl_net_server_simple_inner_server_get(_remote_server);
608 if (fd >= 0) close(fd); 637 efl_net_server_fd_close_on_exec_set(inner_server, EINA_TRUE);
609 return -1; 638 efl_net_server_fd_reuse_address_set(inner_server, EINA_TRUE);
639 }
640 efl_event_callback_add(_remote_server, EFL_NET_SERVER_EVENT_CLIENT_ADD, _client_add, NULL);
641 efl_event_callback_add(_remote_server, EFL_NET_SERVER_EVENT_ERROR, _error, NULL);
642
643 sprintf(address, "127.0.0.1:%d", REMOTE_SERVER_PORT);
644 err = efl_net_server_serve(_remote_server, address);
645 if (err)
646 {
647 fprintf(stderr, "ERROR: could not serve port '%d': %s\n",
648 REMOTE_SERVER_PORT, eina_error_msg_get(err));
649 goto end;
650 }
651 ret = EINA_TRUE;
652end:
653 umask(mask);
654 if (!ret)
655 {
656 efl_del(_remote_server);
657 _remote_server = NULL;
658 }
659 return ret;
610} 660}
611 661
612static Eina_Bool 662static Eina_Bool
613_server_launch(void) 663_server_launch(void)
614{ 664{
615#ifndef _WIN32 665 if (_local_server_create() <= 0) goto err;
616 struct epoll_event event = {0}; 666 if (_remote_server_create() <= 0) goto err;
617 667
618 _epfd = epoll_create (MAX_EVENTS);
619
620 _listening_unix_fd = _listening_unix_socket_create();
621 if (_listening_unix_fd <= 0) goto err;
622 event.data.fd = _listening_unix_fd;
623 event.events = EPOLLIN;
624 epoll_ctl (_epfd, EPOLL_CTL_ADD, _listening_unix_fd, &event);
625
626 _listening_tcp_fd = _listening_tcp_socket_create();
627 if (_listening_tcp_fd <= 0) goto err;
628 event.data.fd = _listening_tcp_fd;
629 event.events = EPOLLIN;
630 epoll_ctl (_epfd, EPOLL_CTL_ADD, _listening_tcp_fd, &event);
631 return EINA_TRUE; 668 return EINA_TRUE;
632err: 669err:
633 if (_listening_unix_fd >= 0) close(_listening_unix_fd); 670 efl_del(_local_server);
634 _listening_unix_fd = -1; 671 efl_del(_remote_server);
635 if (_listening_tcp_fd >= 0) close(_listening_tcp_fd);
636 _listening_tcp_fd = -1;
637#endif
638 return EINA_FALSE; 672 return EINA_FALSE;
639} 673}
640 674
@@ -642,8 +676,14 @@ int
642main(int argc EINA_UNUSED, char **argv EINA_UNUSED) 676main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
643{ 677{
644 eina_debug_disable(); 678 eina_debug_disable();
679 ecore_app_no_system_modules();
680
645 eina_init(); 681 eina_init();
646 ecore_init(); 682 ecore_init();
683 ecore_con_init();
684
685 _retval = EXIT_SUCCESS;
686 _log_dom = eina_log_domain_register("efl_debugd", EINA_COLOR_CYAN);
647 687
648 _string_to_opcode_hash = eina_hash_string_superfast_new(NULL); 688 _string_to_opcode_hash = eina_hash_string_superfast_new(NULL);
649 _opcode_register("Daemon/opcode_register", EINA_DEBUG_OPCODE_REGISTER, _opcode_register_cb); 689 _opcode_register("Daemon/opcode_register", EINA_DEBUG_OPCODE_REGISTER, _opcode_register_cb);
@@ -654,11 +694,12 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
654 _cid_from_pid_opcode = _opcode_register("Daemon/Client/cid_from_pid", EINA_DEBUG_OPCODE_INVALID, _cid_get_cb); 694 _cid_from_pid_opcode = _opcode_register("Daemon/Client/cid_from_pid", EINA_DEBUG_OPCODE_INVALID, _cid_get_cb);
655 _test_loop_opcode = _opcode_register("Test/data_loop", EINA_DEBUG_OPCODE_INVALID, _data_test_cb); 695 _test_loop_opcode = _opcode_register("Test/data_loop", EINA_DEBUG_OPCODE_INVALID, _data_test_cb);
656 696
657 _server_launch(); 697 if (_server_launch()) ecore_main_loop_begin();
658 _monitor(); 698 else _retval = EXIT_FAILURE;
659 699
700 ecore_con_shutdown();
660 ecore_shutdown(); 701 ecore_shutdown();
661 eina_shutdown(); 702 eina_shutdown();
662 703
663 return 0; 704 return _retval;
664} 705}