efl/src/lib/eina/eina_debug_proto.c

126 lines
4.4 KiB
C

/* EINA - EFL data type library
* Copyright (C) 2015 Carsten Haitzler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#include "eina_debug.h"
#ifdef EINA_HAVE_DEBUG
int
_eina_debug_monitor_service_send(int fd, const char op[4],
unsigned char *data, int size)
{
// send protocol packet. all protocol is an int for size of packet then
// included in that size (so a minimum size of 4) is a 4 byte opcode
// (all opcodes are 4 bytes as a string of 4 chars), then the real
// message payload as a data blob after that
unsigned char *buf = alloca(4 + 4 + size);
int newsize = size + 4;
memcpy(buf, &newsize, 4);
memcpy(buf + 4, op, 4);
if (size > 0) memcpy(buf + 8, data, size);
return write(fd, buf, newsize + 4);
}
void
_eina_debug_monitor_service_greet(void)
{
// say hello to our debug daemon - tell them our PID and protocol
// version we speak
unsigned char buf[8];
int version = 1; // version of protocol we speak
int pid = getpid();
memcpy(buf + 0, &version, 4);
memcpy(buf + 4, &pid, 4);
_eina_debug_monitor_service_send(_eina_debug_monitor_service_fd,
"HELO", buf, sizeof(buf));
}
int
_eina_debug_monitor_service_read(char *op, unsigned char **data)
{
unsigned char buf[8];
unsigned int size;
int rret;
// read first 8 bytes - payload size (excl size header) with 4 byte
// opcode that always has to be there
rret = read(_eina_debug_monitor_service_fd, buf, 8);
if (rret == 8)
{
// store size in int - native endianess as it's local
memcpy(&size, buf, 4);
// min size of course is 4 (just opcode) and we will have a max
// size for any packet of 1mb here coming from debug daemon
// for sanity
if ((size >= 4) && (size <= (1024 * 1024)))
{
// store 4 byte opcode and guarantee it's 0 byte terminated
memcpy(op, buf + 4, 4);
op[4] = 0;
// subtract space for opcode
size -= 4;
// if we have no payload - move on
if (size == 0) *data = NULL;
else
{
// allocate a buffer for real payload
*data = malloc(size);
if (*data)
{
// get payload - blocking!!!!
rret = read(_eina_debug_monitor_service_fd, *data, size);
if (rret != (int)size)
{
// we didn't get payload as expected - error on
// comms
fprintf(stderr,
"EINA DEBUG ERROR: "
"Invalid Debug opcode read of %i\n", rret);
free(*data);
*data = NULL;
return -1;
}
}
else
{
// we couldn't allocate memory for payloa buffer
// internal memory limit error
fprintf(stderr,
"EINA DEBUG ERROR: "
"Cannot allocate %u bytes for op\n", size);
return -1;
}
}
// return payload size (< 0 is an error)
return size;
}
else
{
fprintf(stderr,
"EINA DEBUG ERROR: "
"Invalid opcode size of %u\n", size);
return -1;
}
}
fprintf(stderr,
"EINA DEBUG ERROR: "
"Invalid opcode read %i != 8\n", rret);
return -1;
}
#endif