efl debug - clean up debugd and debug cli tool code proto handling

this clenas up protocol handling to share common code and have more
compact and easier to maintain code on both sides here.
This commit is contained in:
Carsten Haitzler 2015-05-08 19:48:26 +09:00
parent 0ba6ddc44a
commit afd2c1c0be
4 changed files with 221 additions and 197 deletions

View File

@ -10,21 +10,19 @@ static const char *expect = NULL;
static Ecore_Con_Server *svr;
static void
_proto(unsigned char *d, unsigned int size)
_do(char *op, unsigned char *d, int size)
{
if (size >= 4)
if (!strcmp(op, "CLST"))
{
char *cmd = (char *)d;
int i, n;
if (!strncmp(cmd, "CLST", 4))
n = (size) / sizeof(int);
if (n < 10000)
{
int i, n;
n = (size - 4) / sizeof(int);
if (n < 10000)
int *pids = malloc(n * sizeof(int));
if (pids)
{
int *pids = malloc(n * sizeof(int));
memcpy(pids, d + 4, n * sizeof(int));
memcpy(pids, d, n * sizeof(int));
for (i = 0; i < n; i++)
{
if (pids[i] > 0) printf("%i\n", pids[i]);
@ -32,78 +30,42 @@ _proto(unsigned char *d, unsigned int size)
free(pids);
}
}
if ((expect) && (!strncmp(cmd, expect, 4)))
ecore_main_loop_quit();
}
}
static Eina_Bool
_server_proto(void)
{
unsigned int size, newsize;
unsigned char *b;
if (!buf) return EINA_FALSE;
if (buf_size < 4) return EINA_FALSE;
memcpy(&size, buf, 4);
if (buf_size < (size + 4)) return EINA_FALSE;
_proto(buf + 4, size);
newsize = buf_size - (size + 4);
if (buf_size == newsize)
{
free(buf);
buf = NULL;
buf_size = 0;
}
else
{
b = malloc(newsize);
memcpy(b, buf + size + 4, newsize);
free(buf);
buf = b;
buf_size = newsize;
}
return EINA_TRUE;
if ((expect) && (!strcmp(op, expect))) ecore_main_loop_quit();
}
Eina_Bool
_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev)
_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev EINA_UNUSED)
{
int i;
for (i = 1; i < my_argc; i++)
{
if (!strcmp(my_argv[i], "list"))
{
unsigned int size = 4;
char *head = "LIST";
send_svr(svr, "LIST", NULL, 0);
expect = "CLST";
ecore_con_server_send(svr, &size, 4);
ecore_con_server_send(svr, head, 4);
printf("send... expect %s\n", expect);
}
else if ((!strcmp(my_argv[i], "pon")) &&
(i < (my_argc - 2)))
{
unsigned int size = 12;
char *head = "PLON";
unsigned char buf[8];
int pid = atoi(my_argv[i + 1]);
unsigned int freq = atoi(my_argv[i + 2]);
i++;
ecore_con_server_send(svr, &size, 4);
ecore_con_server_send(svr, head, 4);
ecore_con_server_send(svr, &pid, 4);
ecore_con_server_send(svr, &freq, 4);
i += 2;
store_val(buf, 0, pid);
store_val(buf, 4, freq);
send_svr(svr, "PLON", buf, sizeof(buf));
ecore_main_loop_quit();
}
else if ((!strcmp(my_argv[i], "poff")) &&
(i < (my_argc - 1)))
{
unsigned int size = 8;
char *head = "PLOFF";
unsigned char buf[4];
int pid = atoi(my_argv[i + 1]);
i++;
ecore_con_server_send(svr, &size, 4);
ecore_con_server_send(svr, head, 4);
ecore_con_server_send(svr, &pid, 4);
store_val(buf, 0, pid);
send_svr(svr, "PLOF", buf, sizeof(buf));
ecore_main_loop_quit();
}
}
@ -111,7 +73,7 @@ _server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server
}
Eina_Bool
_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev)
_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev EINA_UNUSED)
{
ecore_main_loop_quit();
return ECORE_CALLBACK_RENEW;
@ -120,26 +82,17 @@ _server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server
static Eina_Bool
_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev)
{
if (!buf)
char op[5];
unsigned char *d = NULL;
int size;
_protocol_collect(&(buf), &(buf_size), ev->data, ev->size);
while ((size = _proto_read(&(buf), &(buf_size), op, &d)) >= 0)
{
buf = malloc(ev->size);
if (buf)
{
buf_size = ev->size;
memcpy(buf, ev->data, ev->size);
}
_do(op, d, size);
free(d);
d = NULL;
}
else
{
unsigned char *b = realloc(buf, buf_size + ev->size);
if (b)
{
buf = b;
memcpy(buf + buf_size, ev->data, ev->size);
buf_size += ev->size;
}
}
while (_server_proto());
return ECORE_CALLBACK_RENEW;
}
@ -156,7 +109,7 @@ main(int argc, char **argv)
svr = ecore_con_server_connect(ECORE_CON_LOCAL_USER, "efl_debug", 0, NULL);
if (!svr)
{
fprintf(stderr, "ERROR: Cannot connetc to debug daemon.\n");
fprintf(stderr, "ERROR: Cannot connect to debug daemon.\n");
return -1;
}

View File

@ -1 +1,95 @@
#include "efl_debug_common.h"
void
_protocol_collect(unsigned char **buf, unsigned int *buf_size,
void *data, int size)
{
// no buffer yet - duplicate it as out only data
if (!*buf)
{
*buf = malloc(size);
if (*buf)
{
*buf_size = size;
memcpy(*buf, data, size);
}
}
// we have data - append to the buffer and reallocate it as needed
else
{
unsigned char *b = realloc(*buf, *buf_size + size);
if (b)
{
*buf = b;
memcpy(*buf + *buf_size, data, size);
*buf_size += size;
}
}
}
int
_proto_read(unsigned char **buf, unsigned int *buf_size,
char *op, unsigned char **data)
{
unsigned int size, new_buf_size;
unsigned char *b;
// we have no data yet, or not enough - minimum 8 bytes
if (!*buf) return -1;
if (*buf_size < 8) return -1;
// get size of total message
memcpy(&size, *buf, 4);
// if size is invalid < 4 bytes - no message there
if (size < 4) return -1;
// if our total message buffer size is not big enough yet - no message
if (*buf_size < (size + 4)) return -1;
// copy out 4 byte opcode and nul byet terminate it
memcpy(op, *buf + 4, 4);
op[4] = 0;
// take off opcode header of 4 bytes
size -= 4;
// the new buffer size once we remove header+payload is...
new_buf_size = *buf_size - (size + 8);
if (size == 0)
{
*data = NULL;
size = 0;
}
else
{
// allocate new space for payload
*data = malloc(size);
if (!*data)
{
// allocation faild - no message
return -1;
}
memcpy(*data, *buf + 8, size);
}
// if new shrunk buffer size is empty -= just simply free buffer
if (new_buf_size == 0)
{
free(*buf);
*buf = NULL;
}
else
{
// allocate newly shrunk buffer
b = malloc(new_buf_size);
if (!b)
{
// alloc failure - bad. fail proto read then
free(*data);
return -1;
}
// copy data to new smaller buffer and free old, storing new buffer
memcpy(b, *buf + size + 8, new_buf_size);
free(*buf);
*buf = b;
}
// store new buffer size
*buf_size = new_buf_size;
return (int)size;
}

View File

@ -9,4 +9,34 @@
#include <unistd.h>
#include <string.h>
void _protocol_collect(unsigned char **buf, unsigned int *buf_size,
void *data, int size);
int _proto_read(unsigned char **buf, unsigned int *buf_size,
char *op, unsigned char **data);
#define fetch_val(dst, buf, off) \
memcpy(&dst, ((unsigned char *)buf) + off, sizeof(dst))
#define store_val(buf, off, src) \
memcpy(buf + off, &src, sizeof(src))
#define send_svr(svr, 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_server_send(svr, head, 8); \
if (size > 0) ecore_con_server_send(svr, data, size); \
} while (0)
#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)
#endif

View File

@ -5,129 +5,85 @@ typedef struct _Client Client;
struct _Client
{
Ecore_Con_Client *client;
int version;
pid_t pid;
unsigned char *buf;
unsigned int buf_size;
unsigned char *buf;
unsigned int buf_size;
int version;
pid_t pid;
};
static Ecore_Con_Server *svr = NULL;
static Eina_List *clients = NULL;
static void
_proto(Client *c, unsigned char *d, unsigned int size)
static Client *
_client_pid_find(int pid)
{
if (size >= 4)
Client *c;
Eina_List *l;
if (pid <= 0) return NULL;
EINA_LIST_FOREACH(clients, l, c)
{
char *cmd = (char *)d;
if (c->pid == pid) return c;
}
return NULL;
}
if (!strncmp(cmd, "HELO", 4))
static void
_do(Client *c, char *op, unsigned char *d, int size)
{
Client *c2;
Eina_List *l;
if ((!strcmp(op, "HELO")) && (size >= 8))
{
int version;
int pid;
fetch_val(version, d, 0);
fetch_val(pid, d, 4);
c->version = version;
c->pid = pid;
}
else if (!strcmp(op, "LIST"))
{
int n = eina_list_count(clients);
unsigned int *pids = malloc(n * sizeof(int));
if (pids)
{
int version;
int pid;
int i = 0;
memcpy(&version, d + 4, 4);
memcpy(&pid, d + 8, 4);
c->version = version;
c->pid = pid;
}
else if (!strncmp(cmd, "LIST", 4))
{
int n = eina_list_count(clients), i;
unsigned int *pids, size2;
Client *c2;
Eina_List *l;
char *head = "CLST";
pids = malloc(n * sizeof(int));
i = 0;
size2 = 4 + (n * sizeof(int));
EINA_LIST_FOREACH(clients, l, c2)
{
pids[i] = c2->pid;
i++;
}
ecore_con_client_send(c->client, &size2, 4);
ecore_con_client_send(c->client, head, 4);
ecore_con_client_send(c->client, pids, n * sizeof(int));
send_cli(c->client, "CLST", pids, n * sizeof(int));
free(pids);
}
else if (!strncmp(cmd, "PLON", 4))
}
else if ((!strcmp(op, "PLON")) && (size >= 8))
{
int pid;
unsigned int freq = 1000;
fetch_val(pid, d, 0);
fetch_val(freq, d, 4);
if ((c2 = _client_pid_find(pid)))
{
int pid;
unsigned int freq = 1000;
Client *c2;
Eina_List *l;
memcpy(&pid, d + 4, 4);
memcpy(&freq, d + 8, 4);
if (pid > 0)
{
EINA_LIST_FOREACH(clients, l, c2)
{
if (c2->pid == pid)
{
unsigned int size2 = 8;
ecore_con_client_send(c2->client, &size2, 4);
ecore_con_client_send(c2->client, d, 4);
ecore_con_client_send(c2->client, &freq, 4);
break;
}
}
}
}
else if (!strncmp(cmd, "PLOF", 4))
{
int pid;
Client *c2;
Eina_List *l;
memcpy(&pid, d + 4, 4);
if (pid > 0)
{
EINA_LIST_FOREACH(clients, l, c2)
{
if (c2->pid == pid)
{
unsigned int size2 = 4;
ecore_con_client_send(c2->client, &size2, 4);
ecore_con_client_send(c2->client, d, 4);
break;
}
}
}
unsigned char buf[4];
store_val(buf, 0, freq);
send_cli(c2->client, "PLON", buf, sizeof(buf));
}
}
}
static Eina_Bool
_client_proto(Client *c)
{
unsigned int size, newsize;
unsigned char *b;
if (!c->buf) return EINA_FALSE;
if (c->buf_size < 4) return EINA_FALSE;
memcpy(&size, c->buf, 4);
if (c->buf_size < (size + 4)) return EINA_FALSE;
_proto(c, c->buf + 4, size);
newsize = c->buf_size - (size + 4);
if (c->buf_size == newsize)
else if (!strcmp(op, "PLOF"))
{
free(c->buf);
c->buf = NULL;
c->buf_size = 0;
int pid;
fetch_val(pid, d, 0);
if ((c2 = _client_pid_find(pid)))
{
send_cli(c2->client, "PLOF", NULL, 0);
}
}
else
{
b = malloc(newsize);
memcpy(b, c->buf + size + 4, newsize);
free(c->buf);
c->buf = b;
c->buf_size = newsize;
}
return EINA_TRUE;
}
static Eina_Bool
@ -161,26 +117,17 @@ _client_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Clien
Client *c = ecore_con_client_data_get(ev->client);
if (c)
{
if (!c->buf)
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)
{
c->buf = malloc(ev->size);
if (c->buf)
{
c->buf_size = ev->size;
memcpy(c->buf, ev->data, ev->size);
}
_do(c, op, d, size);
free(d);
d = NULL;
}
else
{
unsigned char *b = realloc(c->buf, c->buf_size + ev->size);
if (b)
{
c->buf = b;
memcpy(c->buf + c->buf_size, ev->data, ev->size);
c->buf_size += ev->size;
}
}
while (_client_proto(c));
}
return ECORE_CALLBACK_RENEW;
}