#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
+#include "eina_debug_private.h"
#include <Eina.h>
#include <Ecore.h>
return NULL;
}
-static int
+static void
_send(Client *dest, int opcode, void *payload, int payload_size)
{
int size = sizeof(Eina_Debug_Packet_Header) + payload_size;
hdr->opcode = opcode;
memcpy(buf + sizeof(Eina_Debug_Packet_Header), payload, payload_size);
//printf("%d bytes sent (opcode %s) to %s fd %d\n", size, _opcodes[opcode]->opcode_string, dest->app_name, dest->fd);
- return send(dest->fd, buf, size, 0);
+ if (send(dest->fd, buf, size, 0) != size) perror("send");
}
static void
}
static Eina_Bool
-_dispatch(Client *src, void *buffer, int size)
+_dispatch(Client *src, void *buffer, unsigned int size)
{
Eina_Debug_Packet_Header *hdr = (Eina_Debug_Packet_Header *)buffer;
if (hdr->cid)
if (dest->is_master != src->is_master)
{
hdr->cid = src->cid;
- send(dest->fd, buffer, size, 0);
+ if (send(dest->fd, buffer, size, 0) != size) perror("send");
}
else
{
}
static int
-_data_receive(Client *c, unsigned char **buffer)
+_data_receive(Client *c, unsigned char *buffer)
{
- unsigned char *recv_buf = NULL;
int rret;
- int size = 0;
+ unsigned int size = 0;
if (!c) return -1;
if (rret == sizeof(int))
{
- int cur_packet_size = 0;
- // allocate a buffer for the next bytes to receive
- recv_buf = malloc(size);
- if (!recv_buf) goto error;
+ unsigned int cur_packet_size = 0;
+ if (size > EINA_DEBUG_MAX_PACKET_SIZE) goto error;
while (cur_packet_size < size)
{
- rret = recv(c->fd, recv_buf + cur_packet_size, size - cur_packet_size, 0);
+ rret = recv(c->fd, buffer + cur_packet_size, size - cur_packet_size, 0);
if (rret <= 0) goto error;
cur_packet_size += rret;
}
}
- if (buffer) *buffer = recv_buf;
//printf("%d bytes received from client %s fd %d\n", size, c->app_name, c->fd);
return size;
error:
if (rret == -1) perror("Read from socket");
- if (recv_buf) free(recv_buf);
return -1;
}
#define MAX_EVENTS 1000
int ret = 0;
struct epoll_event events[MAX_EVENTS];
+ unsigned char *buffer = malloc(EINA_DEBUG_MAX_PACKET_SIZE);
Client *c;
// sit forever processing commands or timeouts
if (c)
{
int size;
- unsigned char *buffer;
- size = _data_receive(c, &buffer);
+ size = _data_receive(c, buffer);
// if not negative - we have a real message
- if (size > 0)
+ if (size >= 0)
{
if(!_dispatch(c, buffer, size))
{
// something we don't understand
fprintf(stderr, "Dispatch: unknown command");
}
- free(buffer);
}
else
{
}
#endif
}
+ free(buffer);
#endif
}
-static const char *
+static char *
_socket_home_get()
{
// get possible debug daemon socket directory base
+ char *ret = NULL;
const char *dir = getenv("XDG_RUNTIME_DIR");
if (!dir) dir = eina_environment_home_get();
if (!dir) dir = eina_environment_tmp_get();
- return dir;
+ if (dir)
+ {
+ ret = calloc(1024, 1);
+ strncpy(ret, dir, 1023);
+ }
+ return ret;
}
#ifndef _WIN32
char buf[4096];
struct epoll_event event = {0};
mode_t mask = 0;
- const char *socket_home_path = _socket_home_get();
- char *socket_path = NULL;
- if (!socket_home_path) return EINA_FALSE;
+ char *socket_path = _socket_home_get();
+ if (!socket_path) return EINA_FALSE;
_epfd = epoll_create (MAX_EVENTS);
- socket_path = strdup(socket_home_path);
snprintf(buf, sizeof(buf), "%s/%s", socket_path, SERVER_PATH);
if (mkdir(buf, S_IRWXU) < 0 && errno != EEXIST)
event.events = EPOLLIN;
epoll_ctl (_epfd, EPOLL_CTL_ADD, _listening_slave_fd, &event);
umask(mask);
+ free(socket_path);
return EINA_TRUE;
err:
if (mask) umask(mask);
static Eina_Semaphore _thread_cmd_ready_sem;
-typedef void *(*Eina_Debug_Encode_Cb)(const void *buffer, int size, int *ret_size);
-typedef void *(*Eina_Debug_Decode_Cb)(const void *buffer, int size, int *ret_size);
+typedef void *(*Eina_Debug_Encode_Cb)(const void *buffer, unsigned int size, unsigned int *ret_size);
+typedef void *(*Eina_Debug_Decode_Cb)(const void *buffer, unsigned int size, unsigned int *ret_size);
typedef struct
{
{
unsigned char *total_buf = NULL;
void *new_buf;
- int total_size = size + sizeof(hdr), new_size = 0;
+ unsigned int total_size = size + sizeof(hdr), new_size = 0;
total_buf = alloca(total_size);
memcpy(total_buf, &hdr, sizeof(hdr));
if (size > 0) memcpy(total_buf + sizeof(hdr), data, size);
char c;
int flags = fcntl(_session->fd_in, F_GETFL, 0);
e_debug_begin("Characters received: ");
- fcntl(_session->fd_in, F_SETFL, flags | O_NONBLOCK);
+ if (fcntl(_session->fd_in, F_SETFL, flags | O_NONBLOCK) == -1) perror(0);
while (read(_session->fd_in, &c, 1) == 1) e_debug_continue("%c", c);
- fcntl(_session->fd_in, F_SETFL, flags);
+ if (fcntl(_session->fd_in, F_SETFL, flags) == -1) perror(0);
e_debug_end();
_session->wait_for_input = EINA_FALSE;
_cmd_consume(_session);
size_buf = alloca(size_sz);
if ((rret = read(_session->fd_in, size_buf, size_sz)) == size_sz)
{
- int size;
+ unsigned int size;
if (_session->decode_cb)
{
/* Decode the size if needed */
void *size_decoded_buf = _session->decode_cb(size_buf, size_sz, NULL);
- size = (*(int *)size_decoded_buf) * _session->encoding_ratio;
+ size = (*(unsigned int *)size_decoded_buf) * _session->encoding_ratio;
free(size_decoded_buf);
}
else
{
- size = *(int *)size_buf;
+ size = *(unsigned int *)size_buf;
+ }
+ if (size > EINA_DEBUG_MAX_PACKET_SIZE)
+ {
+ e_debug("Packet too big: %d. The maximum allowed is %d", size, EINA_DEBUG_MAX_PACKET_SIZE);
+ rret = -1;
+ goto end;
}
e_debug("Begin to receive a packet of %d bytes", size);
// allocate a buffer for the next bytes to receive
packet_buf = malloc(size);
if (packet_buf)
{
- int cur_packet_size = size_sz;
+ unsigned int cur_packet_size = size_sz;
memcpy(packet_buf, size_buf, size_sz);
/* Receive all the remaining packet bytes */
while (cur_packet_size < size)
{
// we couldn't allocate memory for payloa buffer
// internal memory limit error
- e_debug("Cannot allocate %u bytes for op", (unsigned int)size);
+ e_debug("Cannot allocate %u bytes for op", size);
goto end;
}
}
}
e_debug("Init module %s", module_name);
+ snprintf(module_path, sizeof(module_path), PACKAGE_LIB_DIR "/lib%s_debug"LIBEXT, module_name);
if (!minfo)
{
- snprintf(module_path, sizeof(module_path), PACKAGE_LIB_DIR "/lib%s_debug"LIBEXT, module_name);
minfo = calloc(1, sizeof(*minfo));
eina_hash_add(_modules_hash, module_name, minfo);
}
// some kind of connection failure here, so close a valid socket and
// get out of here
if (fd >= 0) close(fd);
- if (session) free(session);
+ free(session);
#else
(void) _session;
(void) type;
* Each byte is encoded in two bytes.
*/
static void *
-_shell_encode_cb(const void *data, int src_size, int *dest_size)
+_shell_encode_cb(const void *data, unsigned int src_size, unsigned int *dest_size)
{
const char *src = data;
- int new_size = src_size * 2;
+ unsigned int new_size = src_size * 2;
char *dest = malloc(new_size);
- int i;
+ unsigned int i;
for (i = 0; i < src_size; i++)
{
dest[(i << 1) + 0] = ((src[i] & 0xF0) >> 4) + 0x40;
* Each two bytes are merged into one byte.
*/
static void *
-_shell_decode_cb(const void *data, int src_size, int *dest_size)
+_shell_decode_cb(const void *data, unsigned int src_size, unsigned int *dest_size)
{
const char *src = data;
- int i = 0, j;
+ unsigned int i = 0, j;
char *dest = malloc(src_size / 2);
if (!dest) goto error;
for (i = 0, j = 0; j < src_size; j++)
*/
typedef struct
{
- int size; /**< Packet size including this element */
+ unsigned int size; /**< Packet size including this element */
/**<
* During sending, it corresponds to the id of the destination. During reception, it is the id of the source
* The daemon is in charge of swapping the id before forwarding the packet to the destination.
# define e_debug_end(x...) do { } while (0)
#endif
+/* Max packet size
+ * If the shell is used, the ratio is 2.0. It means the max size (not encoded) should be half.
+ */
+#define EINA_DEBUG_MAX_PACKET_SIZE 10000000
+
typedef struct _Eina_Debug_Session Eina_Debug_Session;
typedef struct _Eina_Debug_Thread Eina_Debug_Thread;
if (ret)
{
char c;
- read(pipeToThread[0], &c, 1);
+ if (read(pipeToThread[0], &c, 1) != 1) _exit_required = EINA_TRUE;
}
else
{